Using Rails 3.1, I have the following:
# state.rb
class State < ActiveRecord::Base
belongs_to :country, :touch => true
after_save :count_total_states
private
def count_total_states
total_states = State.where(:country_id => self.country_id).count
Country.where(:id => self.country_id).update_column(:state, total_states)
end
end
# states_controller.rb
class StatesController < ApplicationController
def create
@country = Country.find(params[:country_id])
@state = @country.states.build(params[:state])
@state.position = State.where(:country_id => @country.id).maximum(:position).to_i + 1
@state.save
end
end
When I create a new object for state, the following error shows:
NoMethodError in StatesController#create
undefined method `update_column' for #<ActiveRecord::Relation:0x1074b0e58>
What is the method going back to the controller? Please advise.
Thanks.
This error is because this:
returns an
ActiveRecord::Relationobject, not a Country. You probably should do one of these two things instead:or
However I would recommend the first option because it does what you really want, finds a record by the ID. Using Where with a primary key is kind of funky, your objective is to return just one exact match and you know its ID so you should just grab it directly.
Note: I would also recommend
update_attributeinstead ofupdate_column, asupdate_columnskips all validation. It’s a good idea to validate unless you really can’t.Better yet, the behavior you’re using is actually encapsulated into a standard Rails practice called “counter cache”. See this blog post and this Railscast for a demonstration of a better way to achieve your goal.