Blankman
Blankman

Reputation: 266940

How to set a property before saving to the database that is not in the form fields

In Rails 5 I can't seem to set a field without having the validation fail and return an error.

My model has:

  validates_presence_of :account_id, :guid, :name

  before_save :set_guid

  private
    def set_buid
      self.guid = SecureRandom.uuid
    end

When I am creating the model, it fails with the validation error saying guid cannot be blank.

def create
  @user = User.new(new_user_params)
  if @user.save
  ..
  ..

   private
     def new_user_params
       params.require(:user).permit(:name)
     end

2

Another issue I found is that merging fields doesn't work now either. In rails 4 I do this:

if @user.update_attributes(new_user_params.merge(location_id: @location_id)

If I @user.inspect I can see that the location_id is not set. This worked in rails 4?

How can I work around these 2 issues? Is there a bug somewhere in my code?

Upvotes: 0

Views: 78

Answers (2)

yoones
yoones

Reputation: 2474

You have at least two options.

  1. Set the value in the create action of your controller

Snippet:

def create
  @user = User.new(new_user_params)
  @user.guid = SecureRandom.uuid
  if @user.save
  ...
end
  1. In your model, use before_validation and add a condition before assigning a value:

Snippet:

before_validation :set_guid

def set_guid
  return if self.persisted?
  self.guid = SecureRandom.uuid
end

Upvotes: 2

Gerry
Gerry

Reputation: 10497

1

Use before_validation instead:

before_validation :set_guid

Check the docs.

2

Hash#merge works fine with rails ; your problem seems to be that user is not updating at all, check that all attributes in new_user_params (including location_id) ara valid entries for User.

If update_attributes fails, it will do so silently, that is, no exception will be raised. Check here for more details.

Try using the bang method instead:

if @user.update_attributes!(new_user_params.merge(location_id: @location_id))

Upvotes: 1

Related Questions