Not adding data to associated table - ruby-on-rails

With the code below and entry is created in the venuetypes table with the correct *venue_id* and time stamps however, the type column remains as null
def new
#new1 = "gfdsgfd"
#venue = Venue.new
#venue.save
#venuetype = #venue.venuetypes.create(:type => "test")
#venuetype.save
respond_to do |format|
format.html # new.html.erb
format.json { render json: #venue }
end
end

Unless you've specified otherwise, rails expects a type column to be used for single table inheritance which is probably causing problems.
Also, venuetypes.create will only save the venue type if it is created successfully, as will the .save call afterwards. You have almost certainly got an error on the venue type which is causing it not to be saved. Try using .save! which will throw an error or by lookins at #venuetype.errors which will contain any error messages that have caused it not to be saved.

Related

How to create/update record if some variables are not set through strong params?

Some of the variables are required for a record but not included in the params. How to then create/update such a record? Would the code below be correct? I belief the new method works, but have doubts about the update method.
New record:
connect = Connect.new(update_params(connection))
connect.first_id = comp1.id
connect.second_id = comp2.id
connect.save
Update existing record:
#If record exists, do this:
connect.first_id = comp1.id
connect.second_id = comp2.id
if connect.save
unless connect.update_attributes(update_connection_params(connection))
return render json: #organization, message: connect.errors.full_messages, status: :bad_request
end
end
Just write validations for these fields, on validation error(s) the record will not be saved and save will return false.
Common pattern is to render the form again, with errors, asking the user to correct
Your code for new record is correct, just check return value of save like for existing:
connect.assign_attributes update_connection_params(connection)
connect.first_id = comp1.id
connect.second_id = comp2.id
if connect.save
redirect_to somewhere_path
else
return render json: #organization, message: connect.errors.full_messages, status: :bad_request
end

Could not find record error while deleting record in Rails

I'm trying to delete a record by passing id of that record. The code looks like this:
def destroy_catalogue_entry
#catalogue_entry = CatalogueEntry.find(params[:catalogue_entry_id])
if #catalogue_entry.destroy
flash[:success] = 'Catalogue entry deleted successfully.'
else
flash[:error] = 'Failed...'
end
end
I'm getting an interesting error. When my function destroy_catalogue_entry is called it shows:
Couldn't find CatalogueEntry with 'id'=16
but as I comment If condition section and render #catalogue_entry as json, the output is printed successfully. So how is it possible? Am I making some silly mistake or is there logical reason. Please enlighten me.
Solved! All I did is this:
def destroy_catalogue_entry
#catalogue_entry = CatalogueEntry.find(params[:catalogue_entry_id])
if #catalogue_entry.destroy
flash[:success] = 'Catalogue entry deleted Successfully'
redirect_to action: :view_catalogue_entries, dc_id: #catalogue_entry.dc_id
else
flash[:success] = 'Failed...'
end
end
When I notice the console, the record was getting deleted successfully but after that there was a SELECT query for the same record, that is why it was throwing the error Couldn't find CatalogueEntry with 'id'=16. As I redirected it, the problem was solved.
I think destroy method is returning an object. In ruby anything other than false or null will be taken to true in if statement. You can do puts on destroy method and see what its returning.
i presume your,
#catalogue_entry = CatalogueEntry.find(params[:catalogue_entry_id])
is returning that error because it cant find CatalogueEntry with id 6, make sure you have CatalogueEntry with that id.

Rails create in model - except attributes

I'm creating an :expense from a :recurringexpense
The :recurring expense has attributes that are not in :expense.
I thought this would work:
def copy_to_expense
#recurringexpense = Recurringexpense.find(params[:id]) # find original recurring expense
#expense = Expense.create(#recurringexpense.attributes).except(:frequency, :last_date)
redirect_to #recurringexpenses, notice: 'Expense was successfully created.'
end
But, I'm getting this:
unknown attribute: frequency
You just need to call except directly on the attributes hash:
#expense = Expense.create(#recurringexpense.attributes.except(:frequency, :last_date))
As you note in your comment, you also need to make sure your keys in the except argument are the right type. You could also do this with
.attributes.symbolize_keys.except(...)

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?
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
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])
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

Rails Parse Active record validation error

I have the following in my controller:
def create
equipment = Equipment.create(:name => params[:name])
errors = equipment.errors.messages
puts "equipment errors: " + errors.inspect
respond_to do |format|
format.json { render :json => #equipment }
end
end
The response from the 'puts' is:
equipment errors: {:name=>["has already been taken"]}
How do I parse the error and get the message?
Thanks
equipment.errors.full_messages.join(", ")
This should give you "Name has already been taken". It concatenates all the errors.
Its just a hash. Access the message with
errors[:name].first
This gets the value of the :name key from the hash, which is an array with one element, and then returns the value of the first element of the array, which is the error message.
With more errors, use Array functions to access all of them and display them appropriately.

Resources