1

カスタム SQL 動作が必要な正しい HABTM (has_and_belongs_to_many) 関係を作成するのに問題があります。アイデアは、単一のサービスまたは複数のサービスに添付できるドキュメントと、単一または複数のドキュメントが添付された同じサービスを持つことです。サービスと同じようにドキュメントに関連するものがより多くの種類になるため、より伝統的なデュアル ID セットアップとは対照的に、関係を収容するモデル 'ResourceDocument' を作成しました。

Document モデルの関連部分は次のとおりです。

class Document < ActiveRecord::Base

  # ... etc ...

  has_and_belongs_to_many :services,
                          :foreign_key => 'document_id',
                          :association_foreign_key => 'resource_id',
                          :join_table => 'resource_documents',
                          :insert_sql => proc {"insert into resource_documents (document_id, resource_id, type) values (#{id}, #{record.id}, 'Service')"}

 # ... etc ...

end

続いて、挿入時に HABTM リレーションを呼び出すサービス仕様 (単体テスト ファイル) の関連部分が続きます。

require 'spec_helper'
describe Service do
  before do
    @org = Org.create!(:name => 'org', :asset_code => 'TRNT')
    # ... etc ...
  end

  # ... etc ...

  it "should not allow a document belonging to different org" do
    new_org = Org.create!({:name => 'another test Org'})
    document = FactoryGirl.create(:document, :org => new_org, :services => [@service])
    @service.documents << [document]
    @service.should_not be_valid
  end
end

を実行するrspecと、この特定の単体テストが失敗し、具体的にはドキュメント割り当ての行 (FactoryGirl.create) が吠え、タイトルに書かれたエラー メッセージが表示されます。ここで何が間違っていますか?私は ruby​​ に関してかなりの初心者であり、具体的には:insert_sql、HABTM リレーションで実行する必要があるという全体的な概念についてです。

ご協力いただきありがとうございます!

4

1 に答える 1

1

は引数としてrecord渡され:insert_sqlます。次のようにする必要があります。

:insert_sql => proc {|record| "insert into resource_documents (document_id, resource_id, type) values (#{id}, #{record.id}, 'Service')"}

したがって、コードは次のようになります。

class Document < ActiveRecord::Base

  # ... etc ...

  has_and_belongs_to_many :services,
                          :foreign_key => 'document_id',
                          :association_foreign_key => 'resource_id',
                          :join_table => 'resource_documents',
                          :insert_sql => proc {|record| "insert into resource_documents (document_id, resource_id, type) values (#{id}, #{record.id}, 'Service')"}

 # ... etc ...

end

編集

Rails 3.1リリースノートから:

以前は、has_and_belongs_to_many 関連付けで :insert_sql および :delete_sql を使用すると、挿入または削除されるレコードを取得するために「record」を呼び出すことができました。これは、引数として proc に渡されるようになりました。

于 2013-03-20T19:33:11.117 に答える