0

Rails 3.2.8 で小さな CMS アプリケーションを作成しています。段落 (基本的にはニュース記事などのタイトル、本文、日付を保持する) とページ (多くのニュース記事などの多くの段落で構成される) のモデルがあります。以下は、日付が変更された場合にのみ段落を更新します。それ以外の場合、たとえば本文が変更されたとしても、段落は更新されません!?

page.update_attributes({"paragraphs_attributes"=>{"0"=>{"_destroy"=>"0", 
             "title"=>"News title", "body"=>"News text", "id"=>"4", 
             "date(3i)"=>"1", "date(2i)"=>"1", "date(1i)"=>"2013"}}})

以下に、モデルの関連部分を示します。

page.rb

class Page < ActiveRecord::Base
  has_many :paragraphs, :dependent => :destroy
  attr_accessible :name, :paragraphs_attributes
  accepts_nested_attributes_for :paragraphs, :allow_destroy => true
end

段落.rb

class Paragraph < ActiveRecord::Base
  belongs_to :page
  attr_accessible :title, :body, :page, :date
  validates :page,  presence: true
end

この奇妙な動作の理由について誰か考えがありますか?

4

2 に答える 2

0

https://github.com/rails/rails/blob/d32965399ccfa2052a4d52b70db1bae0ca16830b/activerecord/lib/active_record/nested_attributes.rb#L72

構文を確認してください

   # Now, when you add the <tt>_delete</tt> key to the attributes hash, with a
    # value that evaluates to +true+, you will destroy the associated model:
    #
    #   member.avatar_attributes = { :id => '2', :_delete => '1' }
    #   member.avatar.marked_for_destruction? # => true
    #   member.save
    #   member.avatar #=> nil
于 2014-11-13T01:26:30.510 に答える
0

もちろん、汚い回避策の可能性があります。最終更新の前に偽の更新を挿入します。これは非常に悪いスタイルであり、更新のためのデータベース アクセスが 2 倍になることに注意してください。しかし、別の解決策が見つからなかったため、次の解決策を思いつきました。

page_controller.rb

class PageController < ApplicationController

  def update

    # Hack: Updating paragraphs fails for some strange reasons if their date 
    # did not change. Updating paragraphs with date changes works as expected.
    # To allow updates in all cases, we first make an update to an impossible
    # date and then make an update to the real date.


    # Define a year, that will never occure in the params.
    # This date will be used for the fake update.
    impossible_year = "1999"

    # Setup the fake params for the first fake update (Change the date fields of 
    # all paragraphs to an impossible date).
    fake_params = params[:page].deep_dup
    par_attrs = fake_params[:paragraphs_attributes]
    par_attrs.keys.each do |key|
      par_attrs[key]["date(1i)"] = impossible_year
    end

    # Perform the fake update.
    @page.update_attributes(fake_params)

    # Finally do the real update with the original params.
    @page.update_attributes(params[:page])
  end
end
于 2013-01-02T10:09:46.103 に答える