I have a model: review.rb
class Review < ActiveRecord::Base
validates :title, :presence => true
belongs_to :product
end
model: product.rb
class Product < ActiveRecord::Base
validates :name, :presence => true
has_many :reviews, :dependent => :destroy
end
and this form: _form.html.haml
=form_for([@product, @product.reviews.build]) do |f|
.field
=f.label :title
%br
=f.text_field :title
with this reviews_controller:
def create
@product = Product.find(params[:product_id])
@review = @product.reviews.create(params[:review])
redirect_to product_path(@product)
end
When I add a review with no title the review doesn’t get created because the title is required (which is good). I’m not sure how to get the errors to show on this association though.
I tried this:
=form_for([@product, @product.reviews.build]) do |f|
-if @product.reviews.errors.any?
.errors
%h2
=pluralize(@product.reviews.errors.count, "error")
%ul
=@product.reviews.errors.full_messages.each do |msg|
%li
=msg
but got this error:
undefined method `errors' for #<ActiveRecord::Relation:0x00000103e31df0>
I tried this:
-if @review.errors.any?
.errors
%h2
=pluralize(@review.errors.count, "error")
%ul
=@review.errors.full_messages.each do |msg|
%li
=msg
And got:
undefined method `errors' for nil:NilClass
In the controller when I:
raise @review.errors.inspect
I can see the errors:
#<ActiveModel::Errors:0x00000103d88c28 @base=#<Review id: nil, title: "", description: "", rating: nil, helpful: nil, product_id: 1, created_at: nil, updated_at: nil>, @messages={:title=>["can't be blank", "is too short (minimum is 5 characters)"]}>
What am I forgetting? How do I get the errors to show?
Thank you
When you make the call to
redirect_to product_path(@product), you are invoking a different controller action, namely theProducts#showaction. The instance variables your views will have been reset. You probably aren’t initializing a@reviewinstance variable in this action which is why you are getting an exception.What you want is something like this
The key is that if the
reviewis unsuccessfully created, you will re-render the page with the same instance variables intact.