hiteshtr
hiteshtr

Reputation: 563

Rails: update mutiple attribute of multiple model concurrently

I want to update values taken from a single form in two different model at the same time, I have written the following code to do so :-

if @mess.update_attributes!(:mess_name => params[:mess_name_update], :mess_capacity => params[:mess_capacity_update]) && @mess_price.update_attributes!(:breakfast_charge => params[:mess_breakfast_charge_update], :lunch_charge => params[:mess_lunch_charge_update], :dinner_charge => params[:mess_dinner_charge_update], :monthly_charge => params[:mess_monthly_charge_update], :semesterly_charge => params[:mess_semesterly_charge_update], :start_date => params[:start_date_update], :end_date => params[:end_date_update], :rebate => params[:rebate_update])
      flash[:success] = "Mess Details Updated Successfully!!"
    else
      flash[:error] = "Some Error! Please Try Again!"
    end

But the above code is giving following error

ActiveRecord::RecordInvalid

Validation failed: Start date can't be blank

Following is the two schema I am using, for @mess its MessType model and for @mess_price its MessPrice model:

MessType
+---------------+--------------+------+-----+---------+----------------+
| Field         | Type         | Null | Key | Default | Extra          |
+---------------+--------------+------+-----+---------+----------------+
| mess_id       | int(11)      | NO   | PRI | NULL    | auto_increment |
| mess_name     | varchar(255) | NO   |     | NULL    |                |
| mess_capacity | int(11)      | NO   |     | NULL    |                |
| start_date    | date         | No   |     | NULL    |                |
| created_at    | datetime     | NO   |     | NULL    |                |
| updated_at    | datetime     | NO   |     | NULL    |                |
+---------------+--------------+------+-----+---------+----------------+

MessPrice
+-------------------+----------+------+-----+---------+----------------+
| Field             | Type     | Null | Key | Default | Extra          |
+-------------------+----------+------+-----+---------+----------------+
| id                | int(11)  | NO   | PRI | NULL    | auto_increment |
| breakfast_charge  | float    | YES  |     | NULL    |                |
| lunch_charge      | float    | YES  |     | NULL    |                |
| dinner_charge     | float    | YES  |     | NULL    |                |
| monthly_charge    | float    | YES  |     | NULL    |                |
| semesterly_charge | float    | YES  |     | NULL    |                |
| rebate            | float    | YES  |     | NULL    |                |
| start_date        | date     | YES  |     | NULL    |                |
| end_date          | date     | YES  |     | NULL    |                |
| mess_id           | int(11)  | YES  | MUL | NULL    |                |
| created_at        | datetime | NO   |     | NULL    |                |
| updated_at        | datetime | NO   |     | NULL    |                |
+-------------------+----------+------+-----+---------+----------------+

Upvotes: 0

Views: 184

Answers (1)

house9
house9

Reputation: 20624

I recommend installing the awesome_print gem - https://github.com/michaeldv/awesome_print

# add to Gemfile
gem 'awesome_print'
# install
bundle

Then the first thing in your controller action do

logger.debug " -----------"
logger.ap params
logger.debug " -----------"

Check your log file log/development.log for the output, it could be the params are coming across correctly but not what you expect? some of the attributes might be nested in another hash key and need to be accessed via params[:something][:xyz]

I would also recommend making the code more readable and running it in a transaction

@mess.mess_name = params[:mess_name_update]
@mess.mess_capacity = params[:mess_capacity_update]

@mess_price.breakfast_charge = params[:mess_breakfast_charge_update]
@mess_price.lunch_charge = params[:mess_lunch_charge_update]
@mess_price.dinner_charge = params[:mess_dinner_charge_update]
@mess_price.monthly_charge = params[:mess_monthly_charge_update]
@mess_price.semesterly_charge = params[:mess_semesterly_charge_update]
@mess_price.start_date = params[:start_date_update]
@mess_price.end_date = params[:end_date_update]
@mess_price.rebate = params[:rebate_update]

# NOTE: an alternative to above is to name your html input fields the rails way
# so that params are sent in a nested hash, i.e. "mess_price[start_date]" -> params[:mess_price][:start_date]
# then you can do @mess_price.update_attributes(params[:mess_price])
# using form_for html helper will automatically apply this style of naming to html input fields

Mess.transaction do 
  # you might want save! vs save - depends if you show validation error in the UI or not
  if @mess.save && @mess_price.save
    flash[:success] = "Mess Details Updated Successfully!!"
  else
    # don't save changes, show validation errors
    raise ActiveRecord::Rollback 
    flash[:error] = "Some Error! Please Try Again!"
  end
end

Upvotes: 1

Related Questions