ruby-on-rails 我可以轻松地为子对象设置accepts_nested_attributes_的值吗?

92dk7w1h  于 2023-10-21  发布在  Ruby
关注(0)|答案(2)|浏览(119)

举个简单的例子,假设我有:

class Garage
  has_many :things
  accepts_nested_attributes_for :things
end

class Thing
  # has a name attribute
  belongs_to :garage
  belongs_to :user
end

class User
...
end

我有一个GaragesController,它接受一个新车库和里面所有东西的POST。

def create
  @garage = Garage.create(safe_garage_params)
end

def safe_garage_params
  params.require(:garage).permit(...)
end

我必须为每个/所有创建的东西设置用户。显然,我可以抓取safe_garage_params散列,并为things_attributes数组中的每个Thing散列设置user。但这看起来很笨拙。有没有更好/更干净的方法?
当然,在我的实际程序中,子数组可以深入几层--这使得爬行更难看。

mpbci0fu

mpbci0fu1#

在Rails 6中,这是可行的。但这太暴力了,我想要一些不那么激烈的东西。

ApplicationRecord
  class << self
    def with_default_scope(some_scope, &block)
      default_scope { some_scope }
      yield
    ensure
      default_scopes.pop
    end
  end
end

new_things = Thing.where(user: some_user)
    garage = Thing.with_default_scope(new_things) do
      Garage.create!(name: "Bob's", things_attributes: [{}, {}])
    end
    expect(garage.things.count).to eq(2)
    expect(garage.things.first.user).to eq(some_user)
    expect(Thing.new.user).to be_blank

在rails 7中,它需要一些更新,因为DefaultScope和all_queries变成了一个东西。

jexiocij

jexiocij2#

也许像这样:

class Garage
  has_many :things
  accepts_nested_attributes_for :things
  
  attribute :things_user

  def things_attributes=(attributes)
    # you'll probably have to get as klutzy as it needs to be here
    attributes.each_value do |h|
      h[:user] ||= things_user
    end
    super
    # or maybe call super first and then set the user on the Thing models
  end
end
>> Garage.create_with(things_user: User.first).new({things_attributes: {"1": {name: "name"}}}).things
=> [#<Thing:0x00007fd7a48b4ce0 id: nil, name: "name", user_id: 1>]

CurrentAttributes

class Current < ActiveSupport::CurrentAttributes
  attribute :user
end

class Thing
  belongs_to :garage
  belongs_to :user, default: -> { Current.user }
end
Current.set(user: User.first) do 
  Garage.create(garage_params)
end

https://api.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html

相关问题