Reputation: 8498
Unfortunately I'm stuck with my comment functionality. The comment
model has a polymorphic association with it's commentables
. Here a sketch of the model:
Furthermore I have a publications
controller, which displays of course some content, the comments and there is an embedded comment form. Another sketch about that:
create
action of the comment
controller.My question is now, how I can I show the validation errors above my embedded form? I know I could use the flash
to show an error, but then the user loses the form data.
def create
@comment = Comment.new(comment_params)
@comment.commentable = find_commentable
if @comment.save
redirect_to polymorphic_url(@comment.commentable, anchor: 'comment-' + @comment.id.to_s)
else
# What do I need to do here?
end
end
How can I make the @comment
available in publications#show
?
I'm on Rails 4.1.
Upvotes: 0
Views: 252
Reputation: 1820
One of the ways to work around the problem is to create a special action for creating comments in PublicationsController
and other commentable controllers (you may want to create a module that you will include in all commentable controllers to avoid repetition and DRY the code).
I didn't have time to check on a test Rails app, so I may have made some typos or other errors, or forget about something in the code above. Still, I hope, the idea is clear. Feel free to edit if you find a bug.
In your PublicationsController
(and other commentable controllers):
def add_comment
# PublicationsController -> Publication
@commentable_class = self.class.to_s[0..-11].singularize.constantize
@commentable = @commentable_class.find(params[:commentable_id]) # it is passed by the form, see below
# set @publication for the publication-specific part of the show view
instance_variable_set('@'+@comentable_class.to_s.underscore, @commentable)
@comment = Comment.new(comment_params.merge(commentable: @commentable))
if @comment.save
redirect_to action: :show, anchor: 'comment-' + @comment.id.to_s
else
render action: :show
end
end
...
def comment_params
# don't forget to define comment_params - as in CommentsController, I guess:
params.require(:comment).permit(:author,:subject,:message)
end
In the show
action of those commentable controllers just do
def show
...
@commentable_class = self.class.to_s[0..-11].singularize.constantize
@comment = Comment.new
@commentable = instance_variable_get('@'+@comentable_class.to_s.underscore)
...
end
In the show
view for the commentables use something like the following form for adding the new comments (based on the provided gist):
- if @comment.errors.any?
%section.errors
%p= t('errors.templates.body')
%ul
- @comment.errors.full_messages.each do |message|
%li= message
= form_for @comment, url: {controller: @commentable_controller, action: :add_comment} do |form|
= hidden_field_tag 'commentable_id', @commentable.id
- unless user_signed_in?
.row
.small-12.columns
= form.label :author
= form.text_field :author, required: true, pattern: '.{3,30}', title: t('errors.messages.not_in_between', from: 3, to: 30)
.row
.small-12.columns
= form.label :subject
= form.text_field :subject, pattern: '.{5,80}', title: t('errors.messages.not_in_between', from: 5, to: 80)
.row
.small-12.columns
= form.label :message
= form.text_area :message, required: true, pattern: '.{30,5000}', title: t('errors.messages.not_in_between', from: 30, to: 5000)
= form.submit class: 'small radius button right'
Upvotes: 1
Reputation: 3053
The way to do this is to add the following code to your show
action in your PublicationsController
: @comment = Comment.new
(or @comment = @publication.comment.new
depending). Then add some sort of <%= @comment.errors.full_messages %>
-type code to your show.html.erb
for the Publication
. Finally, the else
in your comments#create
action should be: render 'publications/show'
.
This will display the errors and will allow your comment form to be <%= form_for @comment ...etc %>
so it will show whatever was typed into the comment form that didn't validate.
Upvotes: 1