我正在尝试(并没有得到很远)了解如何在我的Rails 5应用程序中使用命名空间文件夹。
我的模式中有用户、身份和设置的表。
关联如下:
用户has_many :identities, dependent: :destroy
has_one :setting, dependent: :destroy
设置belongs_to :user
身份belongs_to :user
我已经组织了控制器文件夹,所以我有app/controllers/users/identities_controller。
应用/控制器/用户/setings_controller . Rb每个控制器都有这样的第一行:
class Users::SettingsController < ApplicationController
class Users::IdentitiesController < ApplicationController
我以类似的方式组织了我的视图文件夹。
我有app/views/users/settings/show.
我没有身份视图,除了一个名为_authentications.html.erb的部分。目前存储在app/views/users文件夹中。我试图将它移动到app/views/users/settings文件夹,并从app/views/users/settings/show页面呈现它。
在我的路由文件中有:
resources :users, shallow: true do
scope module: :users do
resources :assign_roles
resources :identities
resources :profiles
resources :settings
end
当我从app/views/users显示页面呈现部分身份验证时,我没有错误。一切工作。我被困住了,因为有些事情我不理解。我不知道那是什么。
我正试图将认证部分移动到app/views/users/settings,以便我可以从app/views/users/settings/show中渲染它。
当我尝试这样做时,我得到一个错误,说:
undefined method `identities' for nil:NilClass
这个错误引用了我的认证部分的这个块:
<% if @user.identities.map(&:provider).include?('linkedin') %>
<span class="glyphicon glyphicon-ok"></span>
<% else %>
<%= link_to 'Connect your Linkedin account', user_linkedin_omniauth_authorize_path %>
<% end %>
我不明白我是否应该尝试在if语句中添加设置?我试过@setting.user。身份(只是猜测),但它没有工作。
有人能看出我做错了什么吗?我似乎找不到一个简单的英语解释如何开始嵌套和命名空间。
添加设置控制器
class Users::SettingsController < ApplicationController
before_action :set_setting, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
after_action :verify_authorized
def index
@settings = Setting.all
authorize @settings
end
def show
# authorize @setting
end
def new
@setting = Setting.new
authorize @setting
end
def edit
end
def create
@setting = Setting.new(setting_params)
authorize @setting
respond_to do |format|
if @setting.save
format.html { redirect_to @setting }
format.json { render :show, status: :created, location: @setting }
else
format.html { render :new }
format.json { render json: @setting.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if @setting.update(setting_params)
format.html { redirect_to @setting }
format.json { render :show, status: :ok, location: @setting }
else
format.html { render :edit }
format.json { render json: @setting.errors, status: :unprocessable_entity }
end
end
end
def destroy
@setting.destroy
respond_to do |format|
format.html { redirect_to settings_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_setting
@setting = Setting.find(params[:id])
authorize @setting
end
# Never trust parameters from the scary internet, only allow the white list through.
def setting_params
params.require(:setting).permit( :newsletter )
end
end
在您的show
动作中没有设置@user
变量,这就是您获得NoMethodError undefined method 'identities' for nil:NilClass
错误的原因。@user
返回部分中的nil
。您可以在控制器中设置@user = current_user
(假设您使用的是设计),或者用current_user
替换@user
。
说了这么多,有什么特别的原因让你想要这样命名你所有的控制器吗?仅仅因为您已经在模型之间设置了has_many
或has_one
关系,并不一定意味着您也必须为您的控制器设置名称空间。如果你有一个很好的理由去做,那就好;如果没有,那么你可以考虑将控制器移出users命名空间。