#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. Большое спасибо. Причина, по которой мне нужны пространства имен, заключается в том, что я пробовал это со всем на верхнем уровне, и это становится действительно беспорядочным, когда нет никакой организации папок. Большое спасибо за объяснение.