首页 > 解决方案 > Rails API 嵌套属性 Find_or_create 以避免重复不起作用

问题描述

我试图在重复的情况下控制嵌套属性,找到该行并使用它而不是创建一个新行,它可以在较低的嵌套级别(即餐点)上正常工作。

但是,如果我使用它,plan.rb 中的注释代码(您可以在下面查看)会使饭菜变为空白,就好像我没有在我的请求中传递任何饭菜一样,对此有什么想法吗?

计划.rb

class Plan < ApplicationRecord
  has_and_belongs_to_many :meals
  has_and_belongs_to_many :days
  has_one_attached :image, dependent: :destroy
  validate :acceptable_image
  accepts_nested_attributes_for :days, reject_if: ->(object) { object[:number].blank? }

  #! this is causing meals to not save
  # # before_validation :find_days
  # def find_days
  #   self.days = self.days.map do |object|
  #     Day.where(number: object.number).first_or_initialize
  #   end
  # end
  #!
end

日.rb

class Day < ApplicationRecord
  has_and_belongs_to_many :meals
  has_and_belongs_to_many :plans
  accepts_nested_attributes_for :meals, reject_if: ->(object) { object[:name].blank? }
  before_validation :find_meals

  def find_meals
    self.meals = self.meals.map do |object|
      Meal.where(name: object.name).first_or_initialize
    end
  end
end

膳食.rb

class Meal < ApplicationRecord
  has_and_belongs_to_many :plans
  has_and_belongs_to_many :days
end

这就是我允许我的参数的方式

def plan_params
    params.require(:plan).permit(:name, :monthly_price, :image_url, days_attributes: [:number, meals_attributes: [:name, :calories, :protein, :fat, :carbohydrates, :categorie]])
end

很抱歉让这么长,但我想提供尽可能多的细节。

标签: ruby-on-railsrubyapinestedassociations

解决方案


由于您正在映射self.days关联,Day.where(number: object.number).first_or_initialize因此将 days 数组替换为Day没有任何meal属性的对象。

您需要在map块内执行类似的操作:

day = Day.where(number: object.number).first_or_initialize
day.attributes = object.attributes
# or similar, to copy the nested attributes provided by the request 

day 

推荐阅读