NothingToSeeHere
NothingToSeeHere

Reputation: 2373

detect if only one attribute is updated in Rails 4 on update_attributes

I am making a blogging app. I need to have two different methods based on how many attributes have been changed. Essentially, if ONLY the publication_date changes I do one thing...even the publication_date and ANYTHING ELSE changes, I do another thing.

posts_controller.rb

def special_update
  if #detect change of @post.publication_date only
    #do something
  elsif # @post changes besides publication_date
  elsif #no changes
  end
end

Upvotes: 2

Views: 1335

Answers (3)

Jerome
Jerome

Reputation: 6217

Or simply compare parameter with existing value

if params[:my_model][:publication_date] != @my_model.publication_date
  params[:my_model][:publication_date] =  Time.now
end

Upvotes: 0

EugZol
EugZol

Reputation: 6555

craig.kaminsky's answer is good, but if you prefer to mess with your controller instead of your model, you can do that as well:

def special_update
  # the usual strong params thing
  param_list = [:title, :body]
  new_post_params = params.require(:post).permit(*param_list)

  # old post attributes
  post_params = @post.attributes.select{|k,v| param_list.include(k.to_sym)}

  diff = (post_params.to_a - new_post_params.to_a).map(&:first)

  if diff == ['publication_date']
    #do something
  elsif diff.empty? # no changes
  else # other changes
  end
end

Upvotes: 1

craig.kaminsky
craig.kaminsky

Reputation: 5598

One way to approach this is in your model using methods provided by ActiveModel::Dirty, which is available to all your Rails Models. In particular the changed method is helpful:

model.changed # returns an array of all attributes changed. 

In your Post model, you could use an after_update or before_update callback method to do your dirty work.

class Post < ActiveRecord::Base
  before_update :clever_method

  private 
  def clever_method
    if self.changed == ['publication_date'] 
      # do something 
    else 
      # do something else 
    end
  end
end

Upvotes: 5

Related Questions