Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
252 views
in Technique[技术] by (71.8m points)

ruby on rails - How to link a parent model to a deeply nested one on creation/update

First off, I've tried looking around but I can't seem to find a definitive answer as to if and how to this if it is possible.

Consider these models

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

Is there any way shape or form where I can have a deeply nested form to create all this so the following can happen ? Or will it truly be necessary to manually create the profile after the group/admin are created ?

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

I'm mainly asking out of curiosity and also because I would find it more "elegant" in a way to truly create a group (in my example) in one line.

PS: the issue with the current way I'm trying things is that group.owner.profiles.first.group is nil so the validations fail

PS2: I do have a 3 line (if you use {} blocks instead) 1 save solution (sort of) that works. But again, I'm curious about a solution where this workaround be required.

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!
question from:https://stackoverflow.com/questions/65939884/how-to-link-a-parent-model-to-a-deeply-nested-one-on-creation-update

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...