2012-01-14 3 views
0

Я подозреваю, что это может быть очень простая ошибка, но я потратил 3 часа на ее поиск, поэтому я подумал, что могу попросить о помощи у сообщества.Rails 3.1: Вложенные атрибуты не сохраняются в форме

Я просматриваю превосходные скринкасты Райана Бэйтса в форме вложенных моделей и пытаюсь применить их к моему собственному проекту. Проблема заключается в том, что вложенный атрибут, похоже, не сохраняет форму. Я могу получить его для сохранения через консоль, но он отображается только как пустые скобки при просмотре формы.

Вот соответствующий код:

Вид формы (с использованием Haml)

= form_for(@article) do |f| 
    - if @article.errors.any? 
    #error_explanation 
     %h2 
     = pluralize(@article.errors.count, "error") 
     prohibited this article from being saved: 
     %ul 
      - @article.errors.full_messages.each do |msg| 
      %li= msg 
    .field 
    = f.label :title 
    %br/ 
    = f.text_field :title 
    .field 
    = f.label :intro 
    %br/ 
    = f.text_area :intro 
    = f.fields_for :subsections do |builder| 
    = render 'subsections_fields', :f => builder 
    .field 
    = f.label :published_at 
    %br/ 
    = f.text_field :published_at 
    .actions 
    = submit_or_cancel(f) 

subsection_fields образуют вид

= f.label :header 
%br/ 
= f.text_field :header 
= f.label :order_id 
= f.number_field :order_id 
%br/ 
= f.label :body 
%br/ 
= f.text_area :body 
%br/ 
= f.check_box :_destroy 
= f.label :_destroy, "Remove Subsection" 
%br/ 

Контроллер

class ArticlesController < ApplicationController 
    def new 
    @article = Article.new 
    3.times { @article.subsections.build } 
    end 

    def create 
    @article = Article.new(params[:article]) 

    if @article.save 
     flash[:notice] = "Successfully created article." 
     redirect_to @article 
    else 
     render :action => 'new' 
    end 
    end 

    def edit 
    @article = Article.find(params[:id]) 
    end 

    def update 
    @article = Article.find(params[:id]) 
    if @article.update_attributes(params[:article]) 
     flash[:notice] = "Successfully updated article." 
     redirect_to @survey 
    else 
     render :action => 'edit' 
    end 
    end 

    def destroy 
    Article.find(params[:id]).destroy 
    flash[:notice] = "Succesfully destroy article." 
    redirect_to articles_url 
    end 

    def show 
    @article = Article.find(params[:id]) 
    end 

    def index 
    @articles = Article.all 
    end 
end 

И модели

class Article < ActiveRecord::Base 
    attr_accessible :title, :intro 

    has_many :subsections, :dependent => :destroy 
    accepts_nested_attributes_for :subsections, :reject_if => lambda { |a| a[:body].blank? }, 
               :allow_destroy => true 
    has_and_belongs_to_many :categories 
    validates :title, :presence => true 
end 


class Subsection < ActiveRecord::Base 
    attr_accessible :header, :body, :order_id 

    belongs_to :article 

    validates :header, :presence => true 
    validates :body, :presence => true 
end 

Любая помощь выяснить это очень ценится.

ответ

0

Я понял ответ на этот вопрос от другого question.

Ответ был установлен мой subsections_attributes как attr_accessible, так что выше модель Статья должна выглядеть следующим образом (я также добавил published_at как attr_accessible):

class Article < ActiveRecord::Base 
    attr_accessible :title, :intro, :subsections_attributes, :published_at 

    has_many :subsections, :dependent => :destroy 
    accepts_nested_attributes_for :subsections, :reject_if => lambda { |a| a[:body].blank? }, 
               :allow_destroy => true 
    has_and_belongs_to_many :categories 
    validates :title, :presence => true 
end 
1

Я не уверен, но попробуйте его с attr_accessible :article_id, а также в вашей модели Subsection?

+0

Я довольно новичок в рельсах, но разве это не опасно? Разве это не позволяет кому-то выполнять массовое задание идентификаторов статей? –

+1

Да, это так, поэтому есть [MassAssignmentSecurity] (http://api.rubyonrails.org/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html#method-i-attr_accessible), чтобы помочь вам санировать ваши атрибуты. Но вы ARE устанавливаете article_ids через массовое присвоение через форму. – Vapire

+0

Возможно, это немного касается касательной, но для моего собственного понимания, не использует '@ article.subsections.build' в контроллере, автоматически устанавливает внешний ключ' article_id'?Я пошел вперед и попробовал все равно, и это не устраняет проблему. –

1

Добавление «attr_accessible» в модель изменяет одностороннее массовое назначение работает в рельсах.

Если вы удалите «attr_accessible» линии в своих моделях, тогда весь ваш код будет работать отлично, как есть.

Метод класса "accepts_nested_attributes_for" добавляет к вашей модели метод "subsections_attributes = (значение)".

Вторым вы добавляете «attr_accessible» к модели, которую теперь вынуждаете добавлять дополнительные записи «attr_accessible» для каждого поля, которое вы хотите назначить с помощью массового присвоения. т.е. когда вы используете Article.new (params [: article]).

Надеюсь, что было ясно.

+0

Я знал это, когда настраивал модели. Проблема возникла, когда я предположил, что, поскольку у меня были методы attr_accessible в дочерней модели для каждого поля, мне нужно было назначить массу, чтобы в родительской модели ничего не нужно было устанавливать. –

Смежные вопросы