Модель Rails, которая имеет как has_one, так и has_many, но с некоторыми ограничениями
Я сопоставляю 2 модели:
User
Account
class Account
has_many :users
class User
has_one :account
Таблица пользователя в качестве учетной записи в ней.
Теперь в модели Account я хочу создать "основного пользователя", у которого только 1 учетная запись.
Таблица пользователя имеет логический флаг: is_primary, как я могу создать has_one на стороне учетной записи для пользователя, у которого есть is_primary и account_id.
Итак, SQL выглядел бы так:
SELECT * FROM users where account_id=123 and is_primary = 1
Итак, я хочу:
У пользователя есть учетная запись.
У учетной записи много пользователей, а также один первичный пользователь.
Ответы
Ответ 1
Подход 1 - добавление новой ассоциации
Добавьте связь has_one
с lambda 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: '[email protected]')
Подход 2 - добавление метода ассоциации
class Account
has_many :users do
def primary
where(:is_primary => true).first
end
end
end
Сейчас:
account.users.primary # returns the primary account
Ответ 2
Вероятно, было бы проще добавить в поле primary_user_id поле "Аккаунт" и добавить ассоциацию "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 boolean), вы можете добавить область как это:
class User
has_one :account
scope :primary, where(:is_primary => true)
end
а затем привяжите область к поиску пользователей:
account = Account.find(1)
primary_user = account.users.primary.first