我有一个编辑表单,预填充当前值。它是一个自定义编辑屏幕(不是rails使用的默认编辑屏幕)以及我使用它的是用户提交将被投票并可能最终应用于记录的更改。但是,在投票的时候,其他东西可能已经改变,如果他们没有提交更改,我不想覆盖这些更改。
编辑:改为我更具体的案例,希望答案对它有用......
我有以下表格:Recipes,RecipeIngredients,RecipeSteps,RecipeChanges。在我的食谱的展示视图中,它显示所有成分/步骤,然后有一个选项卡,然后只更改成分/步骤到表单,以允许用户提交更改。我不希望应用这些更改。相反,我试图创建一个投票系统,人们可以在投票系统上投票。所以我决定将表单中的参数转换为json字符串并将其保存在单个列下的RecipeChanges表中(而不是使用两个表进行成分更改和步骤更改)。下面是表单的代码(删除了html以便更容易看到rails的内容):
<%= form_for @recipe, url: recipe_recipe_changes_path(@recipe), html: {method: "post"}, remote: true do |f| %>
<%= f.fields_for :recipe_ingredients, f.object.recipe_ingredients.order(:order) do |ff| %>
<%= ff.hidden_field :order, class: "position" %>
<%= ff.text_field :ingredient, placeholder: "Add Ingredient (e.g. 3 cups cooked rice)" %>
<label><%= ff.check_box :_destroy %>Remove</label>
<% end %>
<%= f.fields_for :recipe_steps do |ff| %>
<%= ff.hidden_field :order, class: "position"%>
<%= ff.text_area :step %>
<label><%= ff.check_box :_destroy %>Remove</label>
<% end %>
<%= submit_tag "Submit", class: "button" %>
<% end %>
所以这会将配方对象发送到我的RecipeChange控制器,在那里我处理params将它们保存为json字符串,如下所示:
def create
@change = RecipeChange.new
@change.recipe_id = params[:recipe_id]
@change.new_recipe = recipe_change_params.to_json
#if @change.save
#add alert for successfully adding
#else
# add code for error handling
#end
end
这就像我想要的那样,除了它保存所有的成分/步骤,我只想保存他们已经改变的东西。关于如何做到这一点,我有两个想法,但不知道如何实现它。
单击提交按钮时检查字段是否已更改,仅发送已编辑的字段(不确定是否可能)
在控制器中抓取原始配方(我有id,这样很容易)并循环通过配料/步骤并比较它们并删除任何相同的....这是我认为的方法会更好,但不知道如何循环哈希来完成这个
答案 0 :(得分:0)
看看ActiveModel :: Dirty。 http://api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-changed
您可以执行以下操作:
changes = bag.changed_attributes
并获取已更改的属性的哈希值,然后保存带有bag.update_attributes(changes)
的属性。
答案 1 :(得分:0)
现在有点老了,但我遇到过相同或类似的情况,想和别人分享。
在我的情况下,我根据#new动作中的现有对象填充一些嵌套的表单字段。但是,在我的#create动作中,我不想保存这些嵌套的形式参数,除非它们与原始现有对象相比实际被修改。
在这种情况下,ActiveModel::Dirty
始终为true
,因为它会比较[nil, "value"]
。
我首先尝试修改我的#create操作中的params
并将它们与原始现有对象similar to this discussion进行比较,但这很麻烦并且感觉不对。
我最后保存了所有记录,然后在我的模型中使用实例方法进行清理,我在控制器的#create操作中保存后调用。仍感觉有点脏,但它正在发挥作用。
示例:强>
# controllers/changes_controller.rb
# ChangeController#create
def create
# ... shortened for example ...
if @instance.save
@instance.remove_clean_changes
format.html
end
end
# models/change.rb
# Change#remove_clean_changes
# Loop over all original objects and compare the necessary attributes
# to the changes. If they match, they are clean and should be deleted.
def remove_clean_changes
original_objects = self.original_objects
changes = self.changes
original_objects.each do |original_object|
changes.each do |change|
change.destroy if (change.attribute_one == original_object.attribute_one &&
change.original_object_id == original_object.id)
end
end
end