MagicPossum
MagicPossum

Reputation: 311

Preventing UPDATE of record in Rails app where no fields are changed

I'm looking for a way to prevent users from clicking update for the Update method in my Rails app when they have not changed any values. If they do not change any values, my UPDATE method will write empty values in some of the fields, therefore if the user doesn't change any details and just clicks update, I need the app to prevent from updating the record.

Any suggestions would be greatly appreciated.

FYI this is standard cookie cutter Update method:

def update
    if @client.update(client_params)
      redirect_to @client, notice: 'Client was successfully updated.'
    else
      render :edit
    end
  end

Upvotes: 2

Views: 9371

Answers (4)

Qwertie
Qwertie

Reputation: 6483

Are you able to pre fill your form with the existing values? This way if update is pressed the form will send what was there before instead of blank values and the record will not be filled with blank data. Its also good UX to show users the existing values in edit forms.

Upvotes: 1

Pragya Sriharsh
Pragya Sriharsh

Reputation: 559

No need to add custom conditions to check whether your attributes have been modified or not because Rails handles ByDefault.

If modified Active Record object has been retrieved then it will be saved to the database Otherwise no operation will be performed. For better understanding, you can check your console by yourself by running the both queries.

For preventing the empty values being stored in the database. Please check that whether you are using 'PATCH' method types for updating the record or not.

Because it is possible only in one condition:

using 'PUT' method for updating the record and supply only modified 'key-pair' attributes to the rails. Rails will save the other non-specified 'key-value' attributes with empty values.

In Rails, we have two method types for "Update" method.

  1. PUT

(update all or just a portion of the record.)

  1. PATCH

can only update a partial record

To follow better HTTP semantics, Rails will be using the HTTP verb PATCH for updates. PATCH allows for both full and partial updates of a resource, and is more suited to how Rails updates resources.If you are upgrading an existing Rails application, the HTTP verb PUT will still map to the update action in RESTful routes, but it’s recommended to use PATCH moving forward.

Upvotes: 2

Stanko
Stanko

Reputation: 510

You can use the attributes= and changed? methods in conjunction to accomplish your goal.

attributes= mass assigns values from a hash to an instance of a model. changed? returns true if any value on the model changed it's value.

Take the following example:

[1] pry(main)> u = User.all.sample # this returns a random user
=> #<User id: 1319, email: "[email protected]">
[2] pry(main)> u.changed?
=> false
[3] pry(main)> u.attributes = { email: "[email protected]" }
=> {:email=>"[email protected]"}
[4] pry(main)> u.changed?
=> false
[5] pry(main)> u.email
=> "[email protected]"
[6] pry(main)> u.attributes = { email: "[email protected]" }
=> {:email=>"[email protected]"}
[7] pry(main)> u.changed?
=> true
[8] pry(main)> u.email
=> "[email protected]"
[9] pry(main)> u.save
=> true

When applied to your code snippet.

def update
  @client.attributes = client_params

  if @client.changed? && @client.save
    redirect_to @client, notice: 'Client was successfully updated.'
  else
    render :edit
  end
end

Upvotes: 3

Nandhini
Nandhini

Reputation: 665

By default in Rails UPDATE method will be executed only if any one of the value is modified. If no field value is modified the UPDATE method will not run the query, just check and returns the result.

I will give examples for the same. I have an organisation model , in which I initially updated the record with the same existing field values:

Postman update request console log for first update(no values changed)

I just modified one of the field values - internal status console log where only modified value is updated Postman update request for new value

Note: In update it is better to send the old values to avoid empty values being stored in the database.Update expects all the params defined in 'client_params' in your case. If empty params are sent, include a nil check or validation to avoid the same. You can also write a custom update method for the same.

Upvotes: 8

Related Questions