Rails 5 - 命名空间文件夹

时间:2016-10-20 05:53:19

标签: ruby-on-rails ruby namespaces nested

我正在尝试(而不是很远)了解如何在我的Rails 5应用程序中使用命名空间文件夹。

我的架构中有用户,身份和设置的表格。

协会是:

用户

has_many :identities, dependent: :destroy
has_one :setting, dependent: :destroy 

设置

belongs_to :user

身份

belongs_to :user

我已经组织了我的控制器文件夹,以便我有app / controllers / users / identities_controller.rb和app / controllers / users / settings_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.identities(仅作为猜测),但它没有用。

谁能看到我做错了什么?我似乎无法找到关于如何开始嵌套和命名空间的简单英语解释。

添加设置控制器

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

1 个答案:

答案 0 :(得分:0)

您的@user操作中未设置show变量,这就是您收到NoMethodError undefined method 'identities' for nil:NilClass 错误的原因。 @user会在您的部分中返回nil。您可以使用@user = current_user在控制器中设置此项(假设您正在使用设计)或将@user替换为部分中的current_user

说完了所有这些 - 是否有任何特殊原因要您将所有控制器命名为这样?仅仅因为您在模型之间设置了has_manyhas_one关系并不一定意味着您必须为控制器命名。如果你有充分的理由去做,那就好了;如果没有,那么您可以考虑将控制器移出用户名称空间。