2017-01-01 7 views
6

このコードを理解するのに役立ちます。私の知る限りでは私は "< <"をコレクションに追加しますが、ここでレコードを正しく保存します。 .saveメソッド? has_manydocumentationrails - left shift "<<"演算子は自動的にレコードを保存します

#user.rb 
has_many :saved_properties, through: :property_saves, source: :property 

#users_controller.rb 
def update 
    if @user.saved_properties << Property.find(params[:saved_property_id]) 
     render plain: "Property saved" 
end 

答えて

6

多分ソースコードを見るとあなたに役立つでしょう。これはactiverecord<<法に基づく検索の私の道である:

def <<(*records) 
    proxy_association.concat(records) && self 
end 

rails/collection_proxy.rb at 5053d5251fb8c03e666f1f8b765464ec33e3066e · rails/rails · GitHub

def concat(*records) 
    records = records.flatten 
    if owner.new_record? 
    load_target 
    concat_records(records) 
    else 
    transaction { concat_records(records) } 
    end 
end 

rails/collection_association.rb at 5053d5251fb8c03e666f1f8b765464ec33e3066e · rails/rails · GitHub

def concat_records(records, should_raise = false) 
    result = true 

    records.each do |record| 
    raise_on_type_mismatch!(record) 
    add_to_target(record) do |rec| 
     result &&= insert_record(rec, true, should_raise) unless owner.new_record? 
    end 
    end 

    result && records 
end 

rails/collection_association.rb at 5053d5251fb8c03e666f1f8b765464ec33e3066e · rails/rails · GitHub

def insert_record(record, validate = true, raise = false) 
    set_owner_attributes(record) 
    set_inverse_instance(record) 

    if raise 
     record.save!(validate: validate) 
    else 
     record.save(validate: validate) 
    end 
    end 

https://github.com/rails/rails/blob/5053d5251fb8c03e666f1f8b765464ec33e3066e/activerecord/lib/active_record/associations/has_many_association.rb#L32

def insert_record(record, validate = true, raise = false) 
    ensure_not_nested 

    if record.new_record? || record.has_changes_to_save? 
     if raise 
     record.save!(validate: validate) 
     else 
     return unless record.save(validate: validate) 
     end 
    end 

    save_through_record(record) 

    record 
    end 

https://github.com/rails/rails/blob/5053d5251fb8c03e666f1f8b765464ec33e3066e/activerecord/lib/active_record/associations/has_many_through_association.rb#L38

あなたが見ることができるように、最後に、それはsaveメソッドを呼び出しません。

免責事項:私はRailsソースコードに精通していませんが、興味深い質問があります。

6

それは言う:

は、コレクションの主キーに彼らの外国 キーを設定することによって、一つ以上のオブジェクトをコレクションに追加します。この操作 は、親オブジェクトが新しいレコードでない限り、親オブジェクト上で 呼び出しを保存または更新するのを待つことなく、即時にSQLを起動することに注意してください。

2

の関係では、リンク情報がターゲットレコードに保存されます。これは、<<がそのレコードをセットに追加するためにそのレコードを変更する必要があることを意味します。

おそらく、ActiveRecordは、割り当てが成功した場合に代入を行う際に自動的にこれらを保存します。例外は新しいレコードです。関連するレコードには識別子がなく、遅延が必要です。関連するレコードが最終的に作成されると、それらは保存されます。

これはちょっと混乱しているかもしれませんが、おそらく予期せぬことかもしれませんが、実際には99%の時間がかかると思っています。あなたはそれが起こるしたくない場合は、手動でリンクを操作する必要があります。

property = Property.find(params[:saved_property_id]) 
property.user = @user 
property.save! 

基本的には同等ですが、多くの、より詳細なこと。

関連する問題