我需要将多个ID保存到另一个模型中以供参考

时间:2019-02-13 06:43:27

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

我有模型徽章:

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

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

1 个答案:

答案 0 :(得分:2)

假设您希望许多用户具有相同的徽章,则需要的是徽章和用户之间的多对多关联。一个用户可以有许多徽章,而一个徽章可以有许多用户。这需要一个联接表来存储哪个用户具有哪些徽章。

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 << 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