【问题标题】:How to perform autoclearing associated table rows without valid associated id如何在没有有效关联 ID 的情况下执行自动清除关联表行
【发布时间】:2017-08-22 16:20:44
【问题描述】:

我正在尝试找到一种方法来清除与另一个表关联的表中的行。

关键是我正在尝试为食谱创建应用程序。 例如,我不想遇到两个或更多食谱具有相同成分(比如说鸡蛋)的情况。如果我删除一个配方,它将自动删除关联的 Active Record,但我想在例如鸡蛋不会在另一个食谱中使用。

成分模型:

class Ingredient < ApplicationRecord
  belongs_to :recipe, inverse_of: :ingredients

end

配方模型:

class Recipe < ApplicationRecord
    has_many :ingredients, inverse_of: :recipe
    has_many :directions, inverse_of: :recipe

    accepts_nested_attributes_for :ingredients,
                                    reject_if: proc { |attributes| attributes['name'].blank? },
                                    allow_destroy: true
    accepts_nested_attributes_for :directions,
                                    reject_if: proc { |attributes| attributes['step'].blank? },
                                    allow_destroy: true

    validates :tittle, :description, :image, presence: true
    has_attached_file :image, styles: { :medium => "400x400#" }
    validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
end

那么有没有办法(不包括sql查询)来执行这样的操作?

【问题讨论】:

    标签: ruby-on-rails associations rails-activerecord


    【解决方案1】:

    首先创建一个连接配方和成分的连接表。这是设置多对多关联所必需的。

    class Recipe < ApplicationRecord
      has_many :recipe_ingredients
      has_many :ingredients, through: :recipe_ingredients
    
      accepts_nested_attributes_for :ingredients,
         reject_if: proc { |attributes| attributes['name'].blank? },
         allow_destroy: true
    
      # ...
    end
    
    # This model is the master table for ingredients 
    # using a normalized table avoids duplication
    class Ingredient < ApplicationRecord
      has_many :recipe_ingredients
      has_many :ingredients, through: :recipe_ingredients
    end
    
    # This contains the quantity of an ingredient used in a recipe
    class RecipeIngredient < ApplicationRecord
      belongs_to :recipe
      belongs_to :ingredients
    end
    

    然后您可以通过创建回调来删除孤立的行:

    class RecipeIngredient < ApplicationRecord
      belongs_to :recipe
      belongs_to :ingredients
    
      after_destroy do |record|
        ingredient = record.ingredient
        unless ingredient.recipe_ingredients.any?
          ingredient.destroy
        end
      end
    end
    

    【讨论】:

    • 一切似乎都很好,但作为初学者,我不知道如何实现这个.... :(
    猜你喜欢
    • 1970-01-01
    • 2011-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多