繁体   English   中英

Rails 4:如何将具有强参数的嵌套属性传递到模型中

[英]Rails 4: How to pass nested attributes with strong parameters into a model

我有两个嵌套的资源,我在这里工作。 手提包和接收器。

的routes.rb

resources :stashes do
  resources :receivers
end

我有一个表格,我想在提交后创建Stash和Receiver。

<%= form_for(@stash) do |f| %>
  <h2>Who is this Stash for?</h2>
  <div class="reciever-wrap">
    <%= f.fields_for @receiver do |builder| %>
      <div><%= builder.label :first_name %><br />
      <%= builder.text_field :first_name, :autofocus => true %></div>

      <div><%= builder.label :last_name %><br />
      <%= builder.text_field :last_name %></div>

    <% end %>
   <div class="self-check">
      <%= check_box_tag(:self) %>
      <%= label_tag(:self, "This stash is for me") %></div>
  </div>

  <div><%= f.label :occasion, "Is this stash for an occassion?" %><br />
  <%= f.text_field :occasion %></div>

  <div><%= f.label :initial_amount, "How much would you like to spend?" %><br />
  <%= f.text_field :initial_amount %></div>

  <div><%= f.label :length, "How long would you like this Stash to last?" %><br />
  <%= select_tag(:length, options_for_select([['3 Months', 1],['6 Months', 2],['1 Year']])) %>    </div>

  <div><%= f.submit "Start adding gifts to this Stash!", :class => "button" %></div>
<% end %>

我认为首先创建Receiver,然后创建Stash是最有意义的,所以我可以将Stash与Receiver关联起来。 所以在Stashes控制器中(因为Stash在这种形式中是主要的)我在创建动作中有这个:

stashes_controller.rb

def create
  receiver = Receiver.create_receiver(current_user, stash_params)
  if receiver.id
    @stash = Stash.create_stash(current_user, stash_params, receiver)
    if @stash.id
      flash[:success] = "Stash Started!"
      redirect_to stashes_url(@stash), :notice => "Stash Started!"
    else
      render :action => "new", :notice => "Error, try that again"
    end
  end
end

我也在底部定义stash_params:

def stash_params
  params.require(:stash).permit(
    :intitial_amount,
    :length,
    :user_id,
    :first_name,
    :last_name,
    :id,
    :receivers_attributes => [:id, :first_name, :last_name])
end

我能够创建Stash没问题。 但是当我去创建接收器时,我遇到了麻烦。 系统正在创建新的Receiver记录,但不会存储表单中的任何数据。 我猜它与无法访问嵌套的强参数数据有关。

这是Receiver模型中应该保存数据的create_receiver方法,但由于某种原因不是。 我能够保存current_user数据,所以这很好。 它只是来自强属性的数据未被保存:

receiver.rb

def self.create_receiver(current_user, stash_params)
  Receiver.create!(
    :first_name => stash_params[:first_name],
    :last_name => stash_params[:last_name],
    :user_id => current_user
  )
end

我是否需要遍历stash_params才能访问嵌套的receiver_params属性? 我不确定如何访问模型中的嵌套属性。 任何帮助是极大的赞赏!

我也尝试将这个create方法移动到Stash模型中,看看我是否可以从那里访问属性,但我也没有运气。

您可能在模型中缺少accepts_nested_attributes_for

http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

更新#1

既然你已经声明你已经包含了accepts_nested_attributes_for我建议你将你的控制器逻辑整合到像

def create
  @stash = Stash.new(stash_params)
  @stash.user = current_user
  @stash.receivers.each { |r| r.user = current_user }

  if @stash.save
      flash[:success] = "Stash Started!"
      redirect_to stashes_url(@stash), :notice => "Stash Started!"
    else
      render :action => "new", :notice => "Error, try that again"
    end
  end
end

这样您就不必检查是否保存了单个记录,并且强参数应该正常运行

由于您使用的是嵌套属性,因此您应该在create操作中尝试此操作:

def create
  stash = Stash.new(stash_params)
  if stash.save
    flash[:success] = "Stash Started!"
    redirect_to stashes_url(@stash), :notice => "Stash Started!"
  else
    render :action => "new", :notice => "Error, try that again"
  end
end

这样做可以节省存储和接收器所需的所有工作。 accepts_nested_attribute_for保证在保存父对象的同时保存所属对象并从父对象接收正确的id。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM