update_attributes,然后检查属性之一是否已更改 [英] update_attributes, and then check if one of the attributes has changed

查看:27
本文介绍了update_attributes,然后检查属性之一是否已更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个课程模型,用户可以使用表单对其进行编辑和更新.在控制器中,更新方法调用update_attributes(course_params),即强参数.这一切都是标准的,并且工作正常.

I have a Course model that users can edit and update using a form. In the controller, the update method calls update_attributes(course_params), i.e. strong parameters. This is all standard and is working fine.

现在我试图找出更新期间特定属性是否发生变化.特别是,如果用户正在更改课程对象的 points 属性,我还需要将对象的 points_recently_changed 属性标记为 true.快速而肮脏的实现将是这样的:

Now I'm trying to find out if a specific attribute is changing during the update. In particular, if the course object's points attribute is being changed by the user, I also need to mark the object's points_recently_changed attribute to true. The quick-and-dirty implementation would be like this:

def update
  @course = Course.find(params[:id])
  @old_points = @course.points
  @course.update_attributes(course_params)
  @new_points = @course.points
  if @old_points != @new_points
    @course.points_recently_changed = true
    @course.save
  end
end

一种稍微不那么可怕的做法可能是:

A slightly less terrible way of doing it could be:

def update
  @course = Course.find(params[:id])
  @course.points_recently_changed = true if @course.points != params[:course][:points]
  @course.update_attributes(course_params)
end

然而,这些都不能满足我对干净、高效且易于阅读的实现的渴望.理想情况下,update_attributes 可以选择返回更新期间实际更改的属性数组.但它没有.

However, neither of these satisfy my desire for a clean, efficient, and easy-to-read implementation. Ideally, update_attributes would optionally return an array of attributes that have actually changed during the update. But it doesn't.

我查看了 ActiveModel::Dirty,但问题是它只在保存前有效.由于我使用的是 update_attributes,它更新保存,诸如 has_changed? 之类的方法在我的场景中不起作用.

I looked at ActiveModel::Dirty, but the problem with that is it only works before save. And since I'm using update_attributes, which updates and saves, methods such as has_changed? would not work in my scenario.

任何建议将不胜感激.:)

Any suggestions would be appreciated. :)

管理员可以通过以下表单更新课程对象:

Here's the form through which admins can update the course object:

<%= form_for(@course) do |f| %>

  <%= f.label :title %>
  <%= f.text_field :title, required: true %>

  <%= f.label :course_logo %><br />
  <%= f.file_field :course_logo %>

  <%= f.label :description %>
  <%= f.text_field :description, required: true %>

  <%= f.label :worth, "Points" %>
  <%= f.number_field :worth %>

  <%= f.label :tag_ids, "Tags" %>
  <%= f.text_field :tag_ids, data: { load: @course.tags } %>

  <%= f.label :content %>
  <%= f.cktext_area(:content, rows: 10) %>

  <%= f.submit "Save changes", class: "btn btn-large btn-primary" %>

<% end %>

推荐答案

您可以使用 after_validation 回调来更新 points_recently_changed 属性.

You can use after_validation callback to update points_recently_changed attribute.

#course.rb

after_validation :points_changed, if: ->(obj){ obj.points.present? and obj.points_changed? }

def points_changed
  self.points_recently_changed = true
end

说明:

考虑pointsCourse 模型中的一个属性points_changed? 方法将根据points 属性是更新还是返回true 或false不是.

considering points is a attribute in your Course model points_changed? method will return true or false based on whether the points attribute is updated or not .

一个例子

deep@IdeaPad:~/test/test_app$ rails c
2.1.1 :001 > course = Course.find(1)
=> #<Course id: 1, name: "Ruby on Rails", points: 2, points_recently_changed: true, created_at: "2014-06-16 01:51:48", updated_at: "2014-06-16 01:58:07"> 
2.1.1 :002 > course.changed? # will return true of false based on whether the course object has been updated or not
=> false 
2.1.1 :003 > course.points = "11"
=> "11"
2.1.1 :004 > course.points_changed?
=> true 
2.1.1 :005 > course.points_change
=> [2, 11] 

参考 - http://apidock.com/rails/ActiveRecord/Dirty

注意:在保存记录之前,您必须使用 changed? 方法.记录保存后调用 changed? 将返回 false

Note: You have to use changed? method before saving the record. Once the record is saved calling changed? will return false

这篇关于update_attributes,然后检查属性之一是否已更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆