Модель Rails, которая имеет has_one и has_many, но с некоторыми ограничениями - PullRequest
20 голосов
/ 20 февраля 2012

Я сопоставляю 2 модели:

User
Account

class Account 
  has_many :users


class User
  has_one :account

Таблица пользователей в качестве account_id в ней.

Теперь в модели Account я хочу создать «основного пользователя», который будет учетной записью.только 1 выкл.Пользовательская таблица имеет логический флаг: is_primary, как я могу создать has_one на стороне учетной записи для пользователя, которому сопоставлены is_primary и account_id.

Таким образом, SQL будет выглядеть так:

SELECT * FROM users where account_id=123 and is_primary = 1

Итак, я хочу:

У пользователя есть учетная запись.У учетной записи много пользователей, а также один основной пользователь.

Ответы [ 2 ]

45 голосов
/ 20 февраля 2012

Подход 1 - Добавить новую ассоциацию

Добавьте has_one связь с where лямбда-выражением. Это позволяет вам работать в рамках вашей текущей схемы.

class Account 
  has_many :users
  has_one  :primary_user, -> { where(is_primary: true) }, :class_name=> "User"
end

Сейчас:

account.users #returns all users associated with the account
account.primary_user #returns the primary user associated with the account
# creates a user with is_primary set to true
account.build_primary_user(name: 'foo bar', email: 'bar@foo.com')

Подход 2 - Добавить метод ассоциации

class Account 
  has_many :users do
    def primary
      where(:is_primary => true).first
    end
  end
end

Сейчас:

account.users.primary # returns the primary account
6 голосов
/ 20 февраля 2012

Вероятно, было бы проще добавить поле primary_user_id в Account и добавить ассоциацию has_one для primary_user:

class Account
  has_many :users
  has_one :primary_user, :class_name => "User"
end

class User
  has_one :account
end

Если необходимо использовать существующую схему (с логическим флагом: is_primary), вы можете добавить область видимости следующим образом:

class User
  has_one :account
  scope :primary, where(:is_primary => true)
end

и затем связать область видимости с поиском пользователей:

account = Account.find(1)
primary_user = account.users.primary.first
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...