【问题标题】:I need to save multiple ids to another model for reference我需要将多个 id 保存到另一个模型以供参考
【发布时间】:2019-02-13 06:43:26
【问题描述】:

我有一个模特徽章:

t.string :title
t.string :description
t.string :image
t.integer :points

还有一个模特用户:

t.string :first_name
t.string :last_name
t.integer :total_points
t.integer :used_points

我需要为用户添加徽章,以便用户可以查看/查看他们拥有的徽章以及他们是否已经收集了积分。谢谢!

【问题讨论】:

  • 这就是关联的用途。您需要使用has_many :throughhas_and_belongs_to。我更喜欢前者。很多人使用后者。

标签: ruby-on-rails ruby ruby-on-rails-5


【解决方案1】:

假设您希望多个用户拥有相同的徽章,您需要在徽章和用户之间建立多对多关联。一个用户可以有很多徽章,一个徽章可以有很多用户。这需要一个连接表来存储哪个用户拥有哪些徽章。

create_table :badges_users do |t|
  t.belongs_to :user, index: true
  t.belongs_to :badge, index: true
end

由于它只是一个列表,因此不需要此表的模型。使用has_and_belongs_to_many

class Badge < ApplicationRecord
  has_and_belongs_to_many :users
end

class User < ApplicationRecord
  has_and_belongs_to_many :badges
end

向用户添加徽章就像推入数组一样简单。

user.badges << badge

反之亦然。

badge.users << user

他们做同样的事情,在badges_users 中添加一行带有徽章和用户 ID。

See here for more about how to use these collections.

不是将用户的积分存储在用户中,而是从他们的徽章中计算出来。

def total_points
  badges.sum(:points)
end

如果您需要跟踪用户是否“收集”了徽章,则需要将其存储在连接表中并使用模型来获取该信息。

create_table :badge_users do |t|
  t.belongs_to :user, index: true
  t.belongs_to :badges, index: true
  t.boolean :collected, default: false
end

class BadgeUser < ApplicationRecord
  belongs_to :user
  belongs_to :badges
end

然后使用has_many and has_many :through 建立关联。

class User < ApplicationRecord
  has_many :badge_users
  has_many :badges, through: :badge_users
end

class Badge < ApplicationRecord
  has_many :badge_users
  has_many :users, through: :badge_users
end

为用户添加徽章与之前相同,user.badges &lt;&lt; badge

然后我们让用户收集徽章。

# In BadgeUser
def collect
  if collected
    raise "Badge already collected"
  end

  update!(collected: true)
end

# In User
def collect_badge(badge)
  badge_users.find_by( badge: badge ).collect
end

用户可以找到他们收集的徽章。

# In User
def collected_badges
  badges.merge(BadgeUser.where(collected: true))
end

一旦用户可以找到他们收集的徽章,他们就可以合计他们的积分以了解他们使用了多少积分。

# In User
def used_points
  collected_badges.sum(:points)
end

【讨论】:

  • 您也添加了collected 列,您能否详细说明何时设置true
  • @ray 当然,我添加了一个方法来展示如何做到这一点。
  • @Schwern 所以格式是 1 条记录:user_badges = bad_id, user_id,collected.
  • @something 每个用户/徽章组合一个记录。如果用户 1 有 3 个徽章,您将拥有 3 个用户徽章:{ user_id: 1, badge_id: 1, collected: false }, { user_id: 1, badge_id: 2, collected: false }, { user_id: 1, badge_id: 3, collected: false }
  • @Schwern 复制那个。感谢您的帮助!致敬!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-08
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 2020-01-31
  • 2012-07-12
相关资源
最近更新 更多