0

モデルは でUser、多くContactの があります。Postおよびは、 を介してImageに発行できます 。ContactContactPublishment

Userには、公開されたおよびに簡単にアクセスできるようにするメソッドvisible_postsおよびがあります。visible_imagesPostImage

問題は、 と が完全に機能する一方user.visible_imagesuser.visible_posts、これらの関係に依存する仕様が狂ってしまうことです。

visible_images仕様のテストまたは仕様からのテストのいずれかを削除するvisible_postsと、残りのテストはパスします。両方を残すと、2 つ目は失敗します。テストの順序を切り替えることはできますが、それでも 2 番目のテストは失敗します。変でしょ?

これは、Rails 3.2.15 を使用したコード サンプルです。

class User < ActiveRecord::Base
  ...
  has_many :visible_posts, through: :contact_publishments, source: :publishable, source_type: 'Post'
  has_many :visible_images, through: :contact_publishments, source: :publishable, source_type: 'Image'
end

class Contact < ActiveRecord::Base
  ...
  belongs_to :represented_user, class_name: User.name
  has_many :contact_publishments
end

class ContactPublishment < ActiveRecord::Base
  ...
  belongs_to :contact
  belongs_to :publishable, polymorphic: true
end

class Post < ActiveRecord::Base
  ...
  has_many :contact_publishments, as: :publishable, dependent: :destroy
  has_many :contacts, through: :contact_publishments
end

class Image < ActiveRecord::Base
  ...
  has_many :contact_publishments, as: :publishable, dependent: :destroy
  has_many :contacts, through: :contact_publishments
end


describe User do
  ...
  it "#visible_images" do
    user = create :user
    image = create :image
    image.contacts << create(:contact, represented_user: user)
    user.visible_images.should == [image]
  end

  it "#visible_posts" do
    user = create :user
    post = create :post
    post.contacts << create(:contact, represented_user: user)
    user.visible_posts.should == [post]
  end
end
4

1 に答える 1

0

だから私は最終的にそれを解決しましたが、私が望んでいた方法ではありませんでした。手動結合クエリを作成しました。面白いことに、これは私の元のソリューションがトリガーしたのとまったく同じ SQL クエリをトリガーしますが、どういうわけか、これだけが仕様に合格します。Railsのバグ?

class User < ActiveRecord::Base
  ...
  [Post, Image].each do |publishable|
    define_method("visible_#{publishable.name.pluralize.underscore}") do
      publishable.joins(:users).where('users.id' => self.id)
    end
  end
end
于 2014-01-31T19:52:47.360 に答える