简体   繁体   中英

Rails 3 Three Models Join

I don't seem to get this right for some reason, though it sounds simple :/

I have three models :

User(id,name,email)
Skill(id,name,description)
UserSkill(user_id,skill_id,level)

How can i get all skills of a certain user, whether he or she has discovered them or not ?

For example, 3 skills (walk, talk, write). 3 users (John, Mary, Jack).

If Mary walks and writes, how can i get it back as a result like :

Mary => {Skill: walk(includes UserSkill), Skill : talk, Skill : write(includes UserSkill) }

You get the idea :)

I'm assuming you want to set something up like this:

class User < ActiveRecord::Base
  has_many :user_skills
  has_many :skills, :through => :user_skills
end

class Skill < ActiveRecord::Base
  has_many :user_skills
  has_many :users, :through => :user_skills
end

class UserSkill < ActiveRecord::Base
  belongs_to :user
  belongs_to :skill
end

then you can do:

my_user.skills # returns all Skill records assigned to the user
my_user.user_skills.includes(:skill) # this allows you to access :level in addition to Skill attributes

So the way to get both skills and user_skills is to use the :user_skills association. Basic has_many :through. Am I missing something?

Try this:

class User

  def skill_list
    Skill.all(
      :select =>"skills.*, A.user_id AS user_id",
      :joins => "LEFT OUTER JOIN user_skills A 
                 ON A.skill_id = skills.id 
                  AND A.user_id = #{id}").map do |skill|
      skill.name + (skill.user_id.nil? ? "" : "(*)")
    end
  end

end

Now

user = User.find_by_name("Mary")
user.skill_list

Will print:

[
  walk(*),
  talk,
  write(*)
]
user = User.first
user.user_skills.all.map(&:skills)

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