ActiveRecord不保存完整的嵌套数据

时间:2012-01-26 19:29:54

标签: ruby-on-rails ruby activerecord nested-attributes

我有以下型号:

class Innovator < ActiveRecord::Base
  has_many :innovators_medios, :dependent => :destroy, :autosave => true
  has_many :medios, :through => :innovators_medios
  accepts_nested_attributes_for :innovators_medios, :allow_destroy => true, :reject_if => lambda { |a| a['medio_id'].eql? 0 || a['medio_id'].blank? }

  attr_accessor :list_medios

  def self.nuevo
    @new = self.new

    @new.list_medios = Medio.all

    @new.list_medios.count.times { @nuevo.innovators_medios.build }

    @new
  end
end

class InnovatorsMedio < ActiveRecord::Base
  belongs_to :innovator
  belongs_to :medio

  set_primary_key :medio_id
end

控制器:

class InnovadorsController < ApplicationController
  ...

  def new
    @innovator  = Innovator.nuevo
  end

  ...
end

以下对新创新者的观点:

<% form_for @innovator do |f| %>
  <%= f.error_messages %>

  ...  

  <section id="paso-1">
    <div class="page-header">
      <h1>Datos del postulante</h1>
    </div>
    <div class="row">      
        ...                 
        <%= render :partial => 'datos_personales', :locals => { :dato => f } %>   
        ...   
    </div>      
  </section>
<% end %>

相应的部分:

  ...
  <div class="clearfix">
    <%= dato.label :innovadors_medios_id, '¿Cómo se enteró del programa de estímulo a la innovación e investigación?' %>
    <div class="input">
      <ul class="inputs-list">
      <% i = 0 %>
      <% dato.fields_for :innovadors_medios do |im| %>
        <%= render :partial => 'medios/new', :locals => { :medio => im, :nombre => @innovator.list_medios[i].nombre, :id => @innovator.list_medios[i].id } %>
        <% i += 1 %>
      <% end %>
      </ul>
    </div>
    ...

<li id="medio-<%= id %>">
  <label>
    <%= medio.check_box :medio_id, {}, id, 0 %>
    <span><%= nombre %></span>
  </label>
</li>

所有内容都应该呈现。但是,当我保存记录时,AR不会将嵌套属性保存在相应的模型中。它只保存主ID。即:

   innovators_medios
-------------------------
 innovator_id | medio_id
-------------------------
       23     |
       23     |
       23     |
       23     |
-------------------------

日志控制台显示WARNING: Can't mass-assign these protected attributes: medio_id

可能出现什么问题?

3 个答案:

答案 0 :(得分:0)

我认为你的问题是你正在使用InnovatorsMedio类的受保护属性。 Rails定义了某种可访问性,以保护字段不被大量分配。

尝试将attr_accessible :medio_id放在您的InnovatorsMedio课程上,并告诉您是否能解决问题。

答案 1 :(得分:0)

尝试attr_accessible :medio_id, :innovator_id

来自attr_accessible doc:

  

指定可以通过设置的模型属性的白名单   质量分配。

     

与attr_protected一样,如果没有角色,属性的角色是可选的   然后提供:使用默认值。可以使用。来定义角色   :作为选项。

     

这与attr_protected宏相反:Mass-assignment将   仅在此列表中设置属性,以分配其余属性   你可以使用直接编写器方法。这是为了保护敏感   被恶意用户篡改的属性   网址或表单。如果您宁愿从全开默认开始   根据需要限制属性,看看attr_protected。

答案 2 :(得分:0)

:通过docs建议通过表忽略:primary_key选项:

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many

这个较旧的帖子(还有其他帖子)指出在直通表中设置主键的可能性不及2.3.8(或更高版本):

http://railsforum.com/viewtopic.php?id=36186

虽然您的错误消息似乎指向其他内容。