access has_many relation in two different ways ActiveRecord Rails

烂漫一生 提交于 2019-12-11 20:26:05

问题


I need to access institution in two ways. My models are given below:

class Person < ActiveRecord::Base
  has_many :institution_people
  has_many :institution_choices
  has_many :institutions, :through => :institution_people
  has_many :institutions, :through => :institution_choices
  fields........
end

class Institution < ActiveRecord::Base
  has_many :people, :through => :institution_people
  has_many :people, :through => :institution_choices
  has_many :institution_people
  has_many :institution_choices
end

class InstitutionChoice < ActiveRecord::Base
  belongs_to :person
  belongs_to :institution
end

class InstitutionPerson < ActiveRecord::Base
  belongs_to :person
  belongs_to :institution
end

The i setup the models like this is that person can study in different institutions, so for this i setup

has_many :institutions, :through => :institution_people

for person model

But at the same time person can have institution choices, so i setup

has_many :institutions, :through => :institution_choices

for person model.

How should i setup model and association between person and institutions so that i can find institutions from person in both ways.

Right now

Person.first.institutions 

finds from institution_people table, as

has_many :institutions, :through => :institution_people

is at beginning i guess.

Some other techniques are welcomed so that i can get institutions in both ways.


回答1:


In your Person model, try this :

class Person < ActiveRecord::Base
  has_many :institution_people
  has_many :institution_choices
  has_many :institutions_people, :through => :institution_people, :source => :institutions, :class_name => "Institution"
  has_many :institutions_choices, :through => :institution_choices, :source => :institutions, :class_name => "Institution"
end

http://guides.rubyonrails.org/association_basics.html#has_many-association-reference




回答2:


Basically, you need some kind of interface here. What i would do:

in institutions model:

scope :institutions_of, proc { |person| joins(' INNER JOIN (' + Person.institution_ids(person) + ') q
  ON institutions.id = q.ip_iid OR institutions.id = q.ic_iid').where(['institutions.person_id = ?', person_id]

( it joins the query(scope) from Person.rb below )

in Person.rb :

    scope :institution_ids,  proc { |person| select('ip.institution_id ip_idd, ic.institution_id ic_idd
from institution_people ip
inner join institution_choice ic on ip.person_id = ic.person_id').
where(['ip.person_id = ?', person.id])

(this should retrieve all institutions ids from both tables)

ugly as hell, but still might work. You could use is then like: Institution.institutions_of(current_user)




回答3:


If you don't need to keep the result as an ActiveRelation

class Person < ActiveRecord::Base
  has_many :institution_people
  has_many :institution_choices

  def institutions
    institution_people + institution_choices
  end
end

If you DO need the keep it (in order to call person.institutions.order('name'), by example), then it's more complicated:

class Person < ActiveRecord::Base
  has_many :institution_people
  has_many :institution_choices

  scope :institutions, :select => 'select * from (select * from institution_people union all select * from institution_choices) as institutions'
end


来源:https://stackoverflow.com/questions/5701175/access-has-many-relation-in-two-different-ways-activerecord-rails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!