I have a Location model with fields:
Location(id: integer, name: string, address: string, latitude: decimal, longitude: decimal, created_at: datetime, updated_at: datetime, rating: decimal, rating_count: integer)
In my location model, i have the following validations (which work fine):
attr_accessible :name, :address, :latitude, :longitude, :rating, :rating_count
validates :name, :presence => true, :length => { :maximum => 50 }
validates :address, :presence => true
validates :rating, :inclusion => 0..5
validates :rating, :presence => { :message => " cannot be blank" }
I also have a Post model with fields:
Post(id: integer, user_id: integer, location_id: integer, info: string, created_at: datetime, updated_at: date time)
And the following validations:
attr_accessible :info, :address, :name, :rating
belongs_to :user
belongs_to :location
attr_accessor :rating, :address, :name #Virtual attributes for the Post create form
validates :name, :presence => true, :length => { :maximum => 50 }
validates :address, :presence => true
validates :rating, :inclusion => 0..5
validates :rating, :presence => { :message => " cannot be blank" }
Now, the issue is that when I try to create a new Post, the validations for name and address work fine (just as they work for Location), but the validation for rating always fails. Even when I enter a rating of ‘3’, I get the error Rating is not included in the list for some reason, although a rating of ‘3’ is validated correctly if used directly with the Location#create action.
Does anyone know why only the rating validation isn’t working as expected with Post, even though it works fine with Location, and the other validations behave identically with the two models ?
EDIT: Here’s the create action from posts_controller:
def create
@post = current_user.posts.build(params[:post])
@location = Location.find_by_address_and_name(params[:post][:address], params[:post][:name])
if @location.nil?
@location = Location.find_by_address(params[:post][:address])
end
#If the address and the name of the location is the same, just update the rating for that location, and associate the post with the location
if (@location && params[:post][:name] == @location.name)
@post.location_id = @location.id
@location.rating_count += 1
@location.rating = ( (@location.rating + params[:post][:rating].to_r.to_d )/ @location.rating_count )
else
@post.location_id = Location.create(:address => params[:post][:address], :name => params[:post][:name], :rating => params[:post][:rating].to_r.to_d).id
end
@post.save
respond_to do |format|
if @post.save
@location.save! #Update the location only if the post was successful
format.html { redirect_to(@post, :notice => 'Post was successfully created.') }
format.xml { render :xml => @post, :status => :created, :location => @post }
else
format.html { render :action => "new" }
format.xml { render :xml => @post.errors, :status => :unprocessable_entity }
end
end
end
I know this is a LARGE post, but the main point is, 2 identical validations are failing in one place and succeeding in another. One of them validates attributes which are part of the database, the other validates virtual attributes, and I suspect this is the underlying problem.
UPD
add this method
so now you can use your original validation