Rails 5 — Папки с пространством имен

#ruby-on-rails #ruby #namespaces #nested

#ruby-on-rails #ruby #пространства имен #вложенные

Вопрос:

Я пытаюсь (и не очень далеко продвинулся) понять, как использовать папки с пространством имен в моем приложении 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
  

Я организовал свои папки views аналогичным образом.

У меня есть приложение / просмотры / пользователи / настройки / показать.

У меня нет представлений для удостоверений, за исключением частичного имени _authentications.html.erb. В настоящее время это хранится в папке app / views / users. Я пытаюсь переместить его в папку app / views / users / settings и отобразить его со страницы app / views / users / settings / show.

В моем файле routes у меня есть:

 resources :users, shallow: true do
    scope module: :users do
      resources :assign_roles
      resources :identities
      resources :profiles
      resources :settings
    end
  

Когда я выполняю частичную аутентификацию со страницы app / views / users show, у меня нет ошибок. Все работает. Я застрял, потому что есть что-то, чего я не понимаю, и я не знаю, что это такое.

Я пытаюсь переместить частичную аутентификацию в app / views / users / settings, чтобы я мог отображать ее из app / views / users / settings / show.

Когда я пытаюсь это сделать, я получаю сообщение об ошибке, в котором говорится:

 undefined method `identities' for nil:NilClass
  

Эта ошибка ссылается на этот блок моих частичных проверок подлинности:

 <% if @user.identities.map(amp;:provider).include?('linkedin') %>
    <span class="glyphicon glyphicon-ok"></span>
<% else %>  
    <%= link_to 'Connect your Linkedin account', user_linkedin_omniauth_authorize_path %>
<% end %>
  

Я не понимаю, должен ли я каким-то образом пытаться добавить настройки в этот оператор if? Я попробовал 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. Сообщение об ошибке, похоже, указывает на то, что @user равен нулю в вашей части. Можете ли вы поделиться соответствующим кодом действия контроллера?

2. @omnikron — какую часть вы имеете в виду? Если я отображаю _authentications.html.erb, когда он сохраняется в виде файла в views / users и отображается в users / show — все работает. То, что я пытаюсь изменить, это то, что я перемещаю частичную аутентификацию, чтобы сохранить ее в папке views / users / settings и отобразить ее в views / users /settings /show.html.erb. Какой контроллер уместен в этом сценарии?

3. Тот контроллер, действие которого отображает частичное. Я предполагаю, что это контроллер настроек.

4. Я добавил контроллер настроек

Ответ №1:

В вашем @user действии не задана show переменная, поэтому вы получаете эту NoMethodError undefined method 'identities' for nil:NilClass
ошибку. @user возвращает nil в вашем частичном. Вы можете либо установить это в контроллере с помощью @user = current_user (при условии, что вы используете devise), либо заменить @user на current_user в вашем partial .

Сказав все это — есть ли какая-то особая причина, по которой вы хотите использовать пространство имен для всех ваших контроллеров таким образом? То, что вы настроили связь has_many или has_one между вашими моделями, не обязательно означает, что вы также должны использовать пространство имен для своих контроллеров. Если у вас есть веская причина для этого, тогда все в порядке; если нет, то вы могли бы рассмотреть возможность перемещения контроллеров из пространства имен пользователей.

Комментарии:

1. Большое спасибо. Причина, по которой мне нужны пространства имен, заключается в том, что я пробовал это со всем на верхнем уровне, и это становится действительно беспорядочным, когда нет никакой организации папок. Большое спасибо за объяснение.