简体   繁体   中英

Rails has_many :though STI

Lets start with code that may go like this:

class User < ActiveRecord::Base
  has_many :photos
  has_many :submitted_photos
  has_many :posted_photos

  has_many :handshakes, through: :photos
end

class Photo < ActiveRecord::Base
  belongs_to :user
end

class PostedPhoto < Photo
  has_many :handshakes, inverse_of: :poster, foreign_key: 'poster_id'
end

class SubmittedPhoto < Photo
  has_many :handshakes, inverse_of: :submitter, foreign_key: 'submitter_id'
end

class Handshake < ActiveRecord::Base
  belongs_to :submitter, class_name: 'SubmittedPhoto'
  belongs_to :poster,    class_name: 'PostedPhoto'
end

The STI part and associations between photos and handshakes work fine. The problem is getting all user's handshakes through his photos.

Using the code above Rails will obviously complain that model Photo does not have an association called handshakes . Is there any facility in AR that would allow me to specify a relation of this kind? If not, what query would you write to get them?

You could use in User :

has_many :submitted_handshakes, through: :submitted_photos, source: :handshakes
has_many :posted_handshakes, through: :posted_photos, source: :handshakes

I understand this works as is you had:

user.submitted_handshakes ----> user.submitted_photos.handshakes

Obviously handshakes method does not exist in submitted_photos, but AR made this for you by joining tables.

I ended up using the following code, looked like an easiest option to solve this problem.

class User
  def handshakes
    Handshake.where('submitter_id IN (?) OR poster_id IN (?)', submitted_photo_ids, posted_photo_ids)
  end
end

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM