Drew Harris
Drew Harris

Reputation: 486

Rails Activerecord: Update where conditions... else create

I need to check multiple columns of a table to see if I find a match. If I find a match I need to "updateattributes" of the matching record with all of my form params... Else I need to add a new record with all of my form params.

if @somethingtoupdate = Model.where("column1 = ? and column2 = ?", params[:something][:column1], params[:something][:column2])
  if @somethingtoupdate = Model.update_attributes(params[:something])
      redirect_to somewhere_path, :notice => "The existing record was updated"
  else
    render "myformlocation"
  end
else
  @added = Model.new(params[:something])
  if @added.save
    redirect_to somewhere_path, :notice => "The new record was created"  
  else
    render "myformlocation"
  end
end

Update

@somethingtoupdate = Model.where("this_id = ? and that_id = ?", params[:something][:this_id], params[:something][:that_id])
 if ! @somethingtoupdate.empty?
  if @somethingtoupdate.update_attributes(params[:something])
      redirect_to some_path, :notice => "The existing record was updated"
  else
    render "myformlocation"
  end
else
  @added = Model.new(params[:something])
  if @added.save
    redirect_to some_path, :notice => "The new record was created"  
  else
    render "myformlocation"
  end
end

This is where I stand now thanks to @micahbf.

But, I am still getting an error on my "update_attributes" when there is a matching record.

Seems like this should work.... What am I missing or doing wrong?

Upvotes: 0

Views: 1682

Answers (3)

micahbf
micahbf

Reputation: 627

This is because where does not return nil if it doesn't find anything, it returns an empty array, which is still truthy, so the block gets executed.

You can use empty? to check whether to run the block or not.

Note also that if it finds a match, the match will still be returned inside of an array (even if there was only one match). So you will have to do something like call first on the result to take the first returned model and update it.

So, the top might look like:

@somethingtoupdate = Model.where("column1 = ? and column2 = ?", params[:something][:column1], params[:something][:column2])
if ! @somethingtoupdate.empty?
  if @somethingtoupdate.first.update_attributes(params[:something])
      redirect_to some_path, :notice => "The existing record was updated"
  else
    render "myformlocation"
  end
else
  // do stuff if the query found no matches
end

Upvotes: 1

tuo
tuo

Reputation: 586

First of all, Model.update_attributes(params[:something]) is not working (at least in Rails 3.2.12). It should be @somethingtoupdate.update_attributes(params[:something]).

Also, there is an existing method for this kind of purpose: first_or_create.

@somethingtoupdate = Model.where("column1 = ? and column2 = ?", params[:something][:column1], params[:something][:column2]).first_or_create

Upvotes: 0

sagar junnarkar
sagar junnarkar

Reputation: 1270

I think here is short method to find record and if found then update record and if record not found then create it.

@somethingtoupdate = Model.where("column1 = ? and column2 = ?", params[:something][:column1], params[:something][:column2]).first_or_initialize
@somethingtoupdate.update_attributes(params[:something])

Upvotes: 1

Related Questions