I have a scenario where I need to have multiple has_one relationships and be able to access them all at once through a relationship.
Currently I have an STI table, we'll call it Animals. There are subclasses: Lion, Meerkat, Boar
And they all need to relate to multiple Group objects.
So a Lion can be in multiple groups, but a Group may only have one Lion related.
I want to limit and refer to specifically one Lion, Meerkat and Boar. I've tried a simple bridge table, has_many :animals, through: :associated_animals. But there doesn't seem to be an easy way to pull out group.lion. I've also tried doing multiple has_one :lion/:meerkat/:boar relationships, but there was no obvious way to do group.animals.
Is there an STI way to get this functionality through default rails associations or do I have to do a combination of both the has_one :lion and has_many :animals?
Have you tried it like this: app/models/animal.rb
class Animal < ActiveRecord::Base
belongs_to :group
end
class Lion < Animal; end
class Meerkat < Animal; end
Of course you can split out the Lion and Meerkat classes to separate ruby files
app/models/group.rb
class Group < ActiveRecord::Base
has_many :animals
has_one :lion
has_one :meerkat
end
after you run your migrations your schema should look something like this: db/schema.rb
ActiveRecord::Schema.define(version: 20150309234835) do
create_table "animals", force: :cascade do |t|
t.string "name"
t.string "type"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "group_id"
end
create_table "groups", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
Now you should be able to write queries using group:
g = Group.find(1)
g.animals
g.lion
Lion.first.group
Animal.last.group
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.