Мне нужно сохранить несколько идентификаторов в другую модель для справки - PullRequest
0 голосов
/ 13 февраля 2019

У меня есть модель Значки:

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 голосов
/ 13 февраля 2019

Предполагая, что вы хотите, чтобы у многих пользователей был один и тот же значок, вам нужна ассоциация «многие ко многим» между значком и пользователем.Пользователь может иметь много значков, а значок может иметь много пользователей.Для этого требуется таблица соединений для хранения того, у какого пользователя какие значки.

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 со значком и идентификаторами пользователя.

Подробнее об использовании этих коллекций см. Здесь .

Вместо того, чтобы хранить баллы Пользователя в Пользователе, рассчитайте их по их значкам.

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 и 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...