#ruby-on-rails #ruby #activerecord
#ruby-on-rails #ruby #activerecord
Вопрос:
Во-первых, я попытался осмотреться, но, похоже, не могу найти окончательного ответа на вопрос, если и как это сделать, если это возможно.
Рассмотрим эти модели
class Group < ApplicationRecord
belongs_to :owner, class_name: 'User'
has_many :profiles
has_many :users, through: :profiles
validates :name, :owner, presence: true
accepts_nested_attributes_for :owner
end
class User < ApplicationRecord
has_many :profiles
has_many :groups, through: :profiles
has_many :owned_groups, class_name: 'Group', foreign_key: :owner_id, optional: true
validates :name, presence: true
accepts_nested_attributes_for :profiles
end
class Profile < ApplicationRecord
belongs_to :user
belongs_to :group
enum role: [:admin, :moderator, :user]
validates :user, :group, :role, presence: true
end
Есть ли какой-либо способ shape или form, где я могу иметь глубоко вложенную форму для создания всего этого, чтобы могло произойти следующее? Или действительно будет необходимо вручную создать профиль после создания группы / администратора?
deeply_nested_params = params.require(:group).permit(
:name,
owner_attributes: [
:id, # nil on create
:name,
profiles_attributes: [
:id, # nil on create
:role
]
]
)
group = Group.new(deeply_nested_params) #=> #<Group>
group.owner.profiles.first.group == group #=> true
# last but not least
group.valid? #=> true
Я спрашиваю в основном из любопытства, а также потому, что я нашел бы это более «элегантным» способом по-настоящему создать group
(в моем примере) в одной строке.
PS: проблема с текущим способом, которым я пытаюсь, заключается в том, что group.owner.profiles.first.group
значение равно нулю, поэтому проверки завершаются неудачно
PS2: у меня есть 3 строки (если вместо них вы используете {}
блоки) 1 сохранить решение (вроде), которое работает. Но опять же, мне интересно узнать о решении, в котором требуется это обходное решение.
group = Group.new(deeply_nested_params) #=> #<Group>
group.owner.profiles.select do |profile| # select because nothing is saved yet so find won't work
profile.id.nil? # new records only
end.each do |profile|
profile.group = group
end
group.save!
Комментарии:
1. accepts_nested_attributes_for хорошо работает только для ассоциаций «один к одному» и «один ко многим», но ваша групповая пользовательская ассоциация — это «многие ко многим»
2. По логике вещей, вы не можете сохранить запись в таблице profiles, не зная идентификаторов пользователя и группы, поэтому перед созданием профиля необходимо сохранить как пользователя, так и группу.
3. Я хотел бы увидеть дизайн пользовательского интерфейса для создания пользователя, группы и профиля, все вместе, одновременно, за один шаг..
4. @DavidAldridge не обязательно, я добавил редактирование, которое показывает, что вы можете «технически» сделать это в одном
save
, но вам нужно манипулировать несохраненными моделями междуnew
иsave
. Это, конечно, означает, что ее нельзя сократить до одногоcreate!
, например (что является своего рода целью вопроса)5. Ваши модели и остальная часть вопроса не имеют смысла вместе. Нет объяснения, откуда взялся этот
group.admin
метод. Также нет объяснения того, каким должен быть желаемый результат.