允许在Rails 4中创建嵌套资源

时间:2014-09-14 20:46:05

标签: ruby-on-rails

在我的rails app中,用户有一个嵌套的设置对象

resources :user do
  resource :setting
end

现在每次创建设置时,都会创建设置,但不会附加用户ID。 大概这是因为

def setting_params
  params.require(:setting).permit(:region, :publish_to, :language)
end

剥离它。

# GET /settings/new
def new
@setting = Setting.new
end

# GET /settings/1/edit
def edit
end

# POST /settings
# POST /settings.json
def create
 @setting = Setting.new(setting_params)

respond_to do |format|
  if @setting.save
    format.html { redirect_to user_setting_path(@setting, current_user), notice: 'Setting was successfully created.' }
    format.json { render :show, status: :created, location: user_setting_path }
  else
    format.html { render :new }
    format.json { render json: @setting.errors, status: :unprocessable_entity }
  end
end
end

如果我在行中添加:user_id,则不会发生任何变化。

如何在此附加用户?

3 个答案:

答案 0 :(得分:1)

我假设你有params[:id],如果是这样你应该将你的创作动作改为

@setting = User.find(params[:id]).settings.new(setting_params)

如果它被称为:user_id那么它将是

@setting = User.find(params[:user_id]).settings.new(setting_params)

这将在创建的新设置中自动设置foreign_key

答案 1 :(得分:0)

试试这个:

#config/routes.rb
resources :users do
   resources :settings #-> domain.com/users/:user_id/settings/new
end

#app/models/setting.rb
class Setting < ActiveRecord::Base
   belongs_to :user
end

#app/models/user.rb
class User < ActiveRecord::Base
   has_many :settings
end

#app/controllers/settings_controller.rb
class SettingsController < ApplicationController
   def new
     @setting = current_user.settings.new
   end

   def create
     @setting = current_user.settings.new setting_params
     @setting.save
   end

   private

   def setting_params
      params.require(:setting).permit(:region, :publish_to, :language)
   end
end

这将使您能够创建以下视图:

#app/views/settings/new.html.erb
<%= form_for [current_user, @setting] do |f| %>
   <%= f.text_field :region %>
   <%= f.text_field :publish_to %>
   <%= f.text_field :language %>
   <%= f.submit %>
<% end %>

<强>嵌套

嵌套模型/数据在Rails中有点棘手,主要是因为您应该能够将所需数据发送到您的应用程序。

最常用的accepts_nested_attributes_for只有在你想创建记录你正在使用的记录时才真正有效(IE如果你想创建一个{{1}和一个User),你可以使用它(我可以在另一个时间详细说明)

我相信我推荐的方式会为您提供所需的结果。

答案 2 :(得分:0)

@Mohammad AbuShady:不太好,但是你帮助我绊倒了解决方案!谢谢!

你是对的,:user_id是使用的正确密钥。

虽然(如果我错了,请纠正我),只需从params中选择user_id,就可以将设置分配给其他用户(通过走私不同的user_id)。

由于我使用的gem允许我通过访问current_user方法找到当前用户,因此我的代码可以运行,现在看起来像这样:

创建

@setting = User.find(params[:user_id]).create_setting(setting_params)

或以所谓的“保存”方式

@setting = User.find(current_user).create_setting(setting_params)

奇怪的是,.setting.new对我不起作用(设置也没有)但方便create_setting。你知道为什么吗?

<强>更新

def update
  #@setting = params[:setting]
  #@setting = current_user.setting
  #@setting = User.find(params[:user_id]).setting#.update(setting_params)
  @setting = User.find(current_user).setting
  respond_to do |format|
    if @setting.update(setting_params)
      format.html { redirect_to user_setting_path, notice: 'Setting was successfully updated.' }
      format.json { render :show, status: :ok, location: user_setting_path }
    else
      format.html { render :edit }
      format.json { render json: @setting.errors, status: :unprocessable_entity }
    end
  end
end