Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use multiple source_type?

My models are below at present.

user.rb

class User < ActiveRecord::Base
  has_many :authentications
end

authentication.rb

class Authentication < ActiveRecord::Base
  belongs_to :user
  belongs_to :social, polymorphic: true 
end

facebook.rb

class Facebook < ActiveRecord::Base
  has_one :authentication, as: :social
end

twitter.rb

class Twitter < ActiveRecord::Base
  has_one :authentication, as: :social
end

Now thanks to polymorphic association, I can access either Twitter or Facebook objects from an Authentication object as follows:

 authentication.social

Then I want to access the Twitter or Facebook object directly from a User object as well using the :through option to call single method like below:

user.socials

So I tried modifying the User model like the following two samples:

sample1

class User < ActiveRecord::Base
  has_many :authentications
  has_many :socials, through: :authentications, source: :social, source_type: "Twitter"
  has_many :socials, through: :authentications, source: :social, source_type: "Facebook"
end

sample2

class User < ActiveRecord::Base
  has_many :authentications
  has_many :socials, through: :authentications, source: :social, source_type: ["Twitter", "Facebook"]
end

But neither approach worked.

How can I access those objects with a single method like user.socials?

I heard :source and :source_type are for using polymorphic association on :through. If we have to use separate methods like user.twitters and user.facebooks instead of user.socials, I think those options are contradictory to their original concept.

Thanks in advance.

:edit

I'm using

ruby 2.1.2p95
Rails 4.2.0.beta2
like image 724
tarky Avatar asked Oct 30 '14 02:10

tarky


1 Answers

This is a old question, but I believe it will help someone.

I didn't found a great solution, but I've reached a simple solution that may be a slow one.

You have to know all possibles entities associated to your (in your case) Authentication model. Then your User model should have a method named socials. You should have something like this:

class User < ActiveRecord::Base
  has_many :authentications
  has_many :twitters, through: :authentications, source: :social, source_type: "Twitter"
  has_many :facebooks, through: :authentications, source: :social, source_type: "Facebook"

 def socials
  twitters + facebooks
 end
end

Hope it helps someone! :D

like image 76
Fábio Araújo Avatar answered Oct 29 '22 08:10

Fábio Araújo