ActiveRecord не сохраняет полные вложенные данные - PullRequest
0 голосов
/ 26 января 2012

У меня есть следующие модели:

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 не сохраняет вложенный атрибут в соответствующей модели. Сохраняет только основной идентификатор. то есть:

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

Журнал консоли показывает WARNING: Can't mass-assign these protected attributes: medio_id

Что может быть не так?

Ответы [ 3 ]

0 голосов
/ 27 января 2012

Попробуйте attr_accessible :medio_id, :innovator_id.

Из документа attr_accessible doc:

Указывает белый список атрибутов модели, которые можно установить с помощью массовое назначение.

Как и в attr_protected, роль для атрибутов является необязательной, если роль отсутствует затем предоставляется: используется по умолчанию. Роль может быть определена с помощью : как вариант.

Это противоположно макросу attr_protected: массовое назначение только установить атрибуты в этом списке, чтобы назначить остальным атрибутам Вы можете использовать методы прямого писателя. Это предназначено для защиты чувствительных атрибуты от перезаписи злоумышленниками, подделывающими URL-адреса или формы. Если вы хотите начать с полностью открытого по умолчанию и при необходимости ограничьте атрибуты, посмотрите на attr_protected.

0 голосов
/ 01 февраля 2012

Документы: through предполагают, что опция: 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

Хотя кажется, что ваше сообщение об ошибке указывает на что-то еще.

0 голосов
/ 27 января 2012

Я думаю, что ваша проблема в том, что вы используете защищенный атрибут из класса InnovatorsMedio. Рельсы определяют некоторую доступность для защиты полей от массового назначения.

Попробуйте добавить attr_accessible :medio_id в свой класс InnovatorsMedio и скажите, решит ли это вашу проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...