Reputation: 34964
For serialization I want to include an array of sibling records which shares a common foreign key. I currently have the following:
class Foo < ActiveRecord::Base
has_many :other_instances,
source: :foo,
class_name: 'Foo',
foreign_key: 'event_id',
primary_key: 'event_id'
When used in an include, it produces the following queries:
Foo Load (0.2ms) SELECT "foo".* FROM "foo" WHERE "foo"."id" = $1 LIMIT 1 [["id", 21138]]
Foo Load (0.4ms) SELECT "foo".* FROM "foo" WHERE "foo"."event_id" IN (11451)
This mostly works, but the issue is that Foo.other_instances
includes itself. Is there any way to exclude that additional record in rails? The expected includes
would look something like this:
Foo Load (0.4ms) SELECT "foo".* FROM "foo" WHERE "foo"."event_id" IN (11451) AND "foo"."id" NOT IN (21138)
Update:
Attempting to make the condition instance dependent as in @spikermann's results in the following:
Code:
has_many :other_instances,
source: :foo,
class_name: 'Foo',
foreign_key: 'event_id',
primary_key: 'event_id',
->(foo) { where.not(id: foo.id) }
Called with:
Foo.includes(:other_instances).find(21138)
Result:
DEPRECATION WARNING: The association scope 'other_instances' is instance dependent (the scope block takes an argument). Preloading happens before the individual instances are created. This means that there is no instance being passed to the association scope. This will most likely result in broken or incorrect behavior. Joining, Preloading and eager loading of these associations is deprecated and will be removed in the future. (called from check_preloadable! at /home/jordan/prog/knotweed/vendor/bundle/gems/activerecord-4.2.7.1/lib/active_record/reflection.rb:362)
NoMethodError: undefined method `id' for nil:NilClass
Upvotes: 0
Views: 215
Reputation: 106972
What about adding a scope:
has_many :other_instances,
source: :foo,
class_name: 'Foo',
foreign_key: 'event_id',
primary_key: 'event_id',
->(foo) { where.not(id: foo.id) }
Upvotes: 1