0

我有一张配料表。当用户输入一种成分时,它会保存在表格中。现在我注意到许多记录重复,我不希望这样,我想要的是每个记录都被引用(如果它已经存在)。

例如,我在数据库中保存了大约 20 次面粉。我希望它保存一次,对于每个食谱,当用户输入面粉时,它应该只在数据库中引用该成分。我如何实现这一目标?

我已经有一个 Entry 模型(recipe)和一个 join EntryIngredient 模型。因此,每当一个条目保存一个已经存在的成分时,我希望它只引用 EntryIngredient 表中的那个成分(作为外键)而不是创建一个新的成分。

class Ingredient < ActiveRecord::Base
  has_many :entry_ingredients
  has_many :entries, :through => :entry_ingredients

end

class EntryIngredient < ActiveRecord::Base
  belongs_to :entry
  belongs_to :ingredient

  accepts_nested_attributes_for :ingredient, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true

end

class Entry < ActiveRecord::Base
  belongs_to :user
  has_many :entry_ingredients
  has_many :ingredients, :through => :entry_ingredients
  has_many :steps

  accepts_nested_attributes_for :entry_ingredients, :allow_destroy => true
  accepts_nested_attributes_for :steps, :reject_if => lambda { |s| s[:description].blank? }, :allow_destroy => true

end

更新:

动态查找器听起来像是他们做我想要的,特别是find_or_create或者first_or_create但我无法弄清楚如何在我的设置中使用它们。谁能在这里把我推向正确的方向?这是我尝试过的,但我意识到这只是在调用条目#new 时创建一个新成分......不是我想要发生的事情

  #entries_controller.rb
  def new
    @entry = Entry.new
    @entry.entry_ingredients.build.build_ingredient
    @entry.steps.build

    @ingredient = Ingredient.where(params[:ingredient]).first_or_create()

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @entry }
    end
  end

#_entry_ingredient_fields.html.erb
<%= f.fields_for :ingredient do |builder| %>
  <%= builder.label :name %>
  <%= builder.text_field :name, :class => "ingredient_field" %>
<% end %>
4

1 回答 1

1

如果没有看到一些代码,很难确切地知道你需要什么,但如果我理解正确,你只想创建一种成分,前提是它还不存在。

查看 rails 的动态查找器。如果您使用方法名称,例如

@ingredient = Ingredient.find_or_create_by_name("flour")

如果之前没有名称为“flour”的条目,它将创建一个新对象,或者返回一个名为“flour”的现有成分。在这两种情况下,@ingredient 都将保存上述语句返回的所需条目。只有当它还不存在时,Rails 才会为您创建它。

于 2013-03-28T01:26:32.827 回答