【问题标题】:User has several skills用户具有多种技能
【发布时间】:2013-12-31 17:03:07
【问题描述】:

我希望我的用户拥有很多技能。我确实有一个用户和技能数据库表。

我在 user.rb 中使用了 has_many_and_belongs_to 关联

  has_many :skills

我不确定它是否正确。在 skill.rb

  has_and_belongs_to_many :users

我也创建了这样的迁移:

  def change
    create_table :user_skills do |t|
      t.belongs_to :users
      t.belongs_to :skills
   end

这对吗?

如果这是正确的,我该如何为我的用户添加新技能?一般的做法是什么?

我想到的,

在更新操作的用户控制器中,我将更新用户的技能并更新 user_skills 表。 这是怎么做到的?

另外,我如何为特定用户遍历我的 user_skills 表? (在视图中)

任何指导、资源、技巧都会对我有很大帮助,因为这是我第一次在 Rails 中做这样的事情。

谢谢

【问题讨论】:

  • 此答案展示了如何在 ActiveRecord 中正确创建 HABTM 关系:stackoverflow.com/a/5120734/141774
  • 问题:您希望用户能够与其他用户拥有相同的技能吗?这样我就知道 habtm 是否是您需要的关联。

标签: ruby-on-rails ruby-on-rails-4


【解决方案1】:

在 Rails 中,大多数人更喜欢使用 has_many :through 而不是 habtm 关联。以下是如何使用它的指南:ActiveRecord guide

用户和技能的 has_many through 关联在您的相关模型中如下所示:

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

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

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

您的迁移将如下所示:

def change
  create_table :user_skills do |t|
    t.references :user, index: true
    t.references :skill, index: true
  end
end

迁移中的索引用于更快地查找使用 reference_id。建议对所有引用都这样做。

要为您的用户添加新技能,您可以参考此SO answer

要更新用户的技能,您可以这样做:

@skill = @user.skills.find(params[:skill_id])
@skill.update(skill_params)

要创建用户的技能,您可以这样做:

@user.skills.create(skill_params)

要向用户添加技能,您可以在更新操作中执行此操作:

@user.update(user_params)

#app/views/users/edit.html.erb
<%= f.select :skill_ids, Skill.all.collect {|x| [x.name, x.id]}, {}, :multiple => true %>

当使用 has_many through 时,您无需通过 user_skills 表来获取特定用户。但是,您可能需要从技能中获取特定用户。为此:

@skill.users.find(user_id)

希望有帮助!

【讨论】:

    【解决方案2】:

    如果您也将 user 设置为 have_and_belong_to_many :skills 那么这将起作用。

    要为用户创建新技能

    user.skills.create!{...}

    或将现有技能与用户相关联

    用户

    “在我的用户控制器更新操作中,我将更新用户的技能并更新 user_skills 表。这是如何完成的?”

    user = User.find 参数[:id]

    技能 = user.skills

    然后你就可以对用户技能做你喜欢做的事情了

    “另外,我如何为特定用户遍历我的 user_skills 表?(在视图中)”

    user.skills.each 做 |skill|

    ...

    结束

    有关 HABTM 协会的更多信息,请参阅http://guides.rubyonrails.org/association_basics.html#has-and-belongs-to-many-association-reference

    【讨论】:

      【解决方案3】:

      请原谅我如果我弄错了,请尝试填补空白,但我认为您想要看起来像这样的东西。

      控制器

        def index
          #to fetch all skills associated to users (add where u.id=? to fetch for a single user)
          @users = User.select("u.name, s.name").
          from("users u, skills s, users_skills us").
          where("u.id = us.user_id").
          where("s.id = us.skill_id")
        end
      
      
      
        def new
          @user = User.new
          @skills = Skill.all
        end
      
        def create
          @user = User.new(params[:user])
          ...............................
        end
      

      在创建表单中

      <%= form_for @user do |f| %>
        <%= f.collection_select(:skill_ids, @skills,:id,:name)%>
        <%= f.submit "Save" %>
      <% end %>
      

      【讨论】:

        【解决方案4】:

        为了使用HABTM,您需要一个名为users_skills 或skills_users 的连接表(不确定是否重要)。它应该包含两个名为 user_id 和 Skill_id 的整数列。您也应该为它们创建索引。在你的用户模型中你想要has_and_belongs_to_many :skills,在你的技能模型中你想要has_and_belongs_to_many :users

        【讨论】:

          【解决方案5】:

          您需要has_and_belongs_to_many 在关系的双方

          class User
            has_and_belongs_to_many :skills
          
          class Skill
            has_and_belongs_to_many :users
          

          或者(我认为更好)是使用has_many :through

          class User
            has_many :user_skills
            has_many :skills, through: :user_skills
          
          class Skill
            has_many :user_skills
            has_many :users, through: :user_skills
          

          【讨论】:

            猜你喜欢
            • 2010-12-28
            • 1970-01-01
            • 2021-01-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-04-22
            相关资源
            最近更新 更多