Comments not displaying from rendered form - ruby-on-rails

I am new to Ruby and I am trying to display comments on my show page but when I create a comment it does not display. I have rendered a partial on my show page in order to display the comments but they do not appear.
The strange thing is that the create action works but it takes me to this page: http://localhost:3000/hairstyles/2/comments which has nothing on it (in my app this page is under views>comments>create.html.erb) instead i'd like it to go to the view page for the hairstyle and display the comment..........
If anyone can help and see if there are any errors in my code I'd be grateful. Thanks in advance.
Comments Controller:
class CommentsController < ApplicationController
def new
#hairstyle = Hairstyle.find(params[:hairstyle_id])
#comment = Comment.new
end
def create
#comment = Comment.new(comment_params)
#hairstyle = Hairstyle.find(params[:hairstyle_id])
#comment.save
end
def destroy
end
end
private
def comment_params
params.require(:comment).permit(:content)
end
Hairstyle view page where I want to display the comments:
<div class="container">
<div>
<%= cl_image_tag #hairstyle.photo, width: 300, height: 200, crop: :fill %>
<h1><%= #hairstyle.name %></h1>
<p><%= #hairstyle.description%></p>
<p><%= #hairstyle.category%></p>
<p><%= #hairstyle.video_url %></p>
</div>
</div>
<div>
<%= link_to 'Back', hairstyles_path %>
</div>
<h6>Comments for: <%= #hairstyle.name %> <small><%= %></small></h6>
<h2>
<%= pluralize #hairstyle.comments.size, "comment" %>
</h2>
<div id="comments">
<% if #hairstyle.comments.blank? %>
Be the first to leave a comment for <%= #hairstyle.name %>
<% else %>
<% #hairstyle.comments.each do |comment| %>
<%= render 'comments/show', comment: comment %>
<% end %>
<% end %>
</div>
<%= render 'comments/form', comment: #comment %>
Comments form i am rendering which does work and is displayed:
views>comments>_form.html.erb
<div class="flex-box">
<%= simple_form_for([ #hairstyle, comment ]) do |form| %>
<%= form.input :content, as: :text %>
<%= form.button :submit %>
<% end %>
</div>
Comments content that I am rendering that does not display once I have added a comment to my hairstyle on the show page:
views>comments>_show.html.erb
<p><%= comment.content %></p>

The default behavior of rails controllers is it will redirect to the index page after the create method. that's why you are redirected to that path.
you can simply use redirec_to in your create method in your comment controller like below
def create
#comment = Comment.new(comment_params)
#hairstyle = Hairstyle.find(params[:hairstyle_id])
#comment.save
redirect_to hairstyle_path(#comment.hairstyle)
end

You never link your comment to your hairstyle, your hairstyle_id from your comment is nil this is why #hairstyle.comments returns an empty array
def create
#hairstyle = Hairstyle.find(params[:hairstyle_id])
#comment = #hairstyle.comments.build(comment_params)
# equivalent to:
# comment = Comment.new(comment_params)
# comment.hairstyle = #hairstyle
if comment.save
redirect_to hairstyle_path(#hairstyle)
else
# handle errors
end
end

Related

ruby on rails nested form create

I have user model that has many reviews, and each review has many replies.
I want to allow the user to reply under a review.
In a profile page (coming from a profile controller and show action), I want to be able to create replies.
<div class="reply-box d-none" id="reply-box">
<%= form_with(model: Reply, url: new_user_review_reply_path(#user, #review)) do |reply| %>
<%= reply.hidden_field :user_id, value: #user %>
<%= reply.hidden_field :review_id, value: #review %>
<%= reply.text_field :reply_content%>
<div class="comment-box-btns mb-5">
<%= reply.submit "submit", class: 'submit-btn d-inline-block ml-2 float-right'%>
<div class="cancel-btn d-inline-block float-right">cancel</div>
</div>
<% end %>
</div>
Here is the route.rb
resources :users do
resources :reviews do
resources :replies
end
end
Here is the reply controller:
class RepliesController < ApplicationController
def new
#user = User.find(params[:user_id])
#reivew = #user.reviews.find(params[:review_id])
#reply = #reivew.replies.new
end
def create
#user = User.find(params[:user_id])
#reivew = #user.reviews.find(params[:review_id])
#reply = #reivew.replies.create!(reply_params)
respond_to do |format|
format.html {redirect_to(profile_path(param[:user_id]))}
format.js
end
end
private
def reply_params
params.require(:reply).permit(
:reply_content,
:user_id,
:review_id
)
end
end
I don't know how to set up the "form_with". So far it just says
undefined method `reply_content' for #<Class:0x007f8c7396aaa8>
reply_content is the field in reply I want to create using the text_area.
I am very confused. Any help would be greatly appreciated.
As you have already intitilize #reply = #reivew.replies.new in new action so you should use this #reply object with reply form, also i don't think that you need not to explicitly provide value: user_id and value: review_id
<div class="reply-box d-none" id="reply-box">
<%= form_for #reply, url: new_user_review_reply_path(#user, #review) do |reply| %>
<%= reply.hidden_field :user_id %>
<%= reply.hidden_field :review_id %>
<%= reply.text_field :reply_content%>
<div class="comment-box-btns mb-5">
<%= reply.submit "submit", class: 'submit-btn d-inline-block ml-2 float-right'%>
<div class="cancel-btn d-inline-block float-right">cancel</div>
</div>
<% end %>
</div>

how to display comments for posts in rails (by iteration )

I managed to link comments to their posts in rails but the remaining thing is displaying them and here is my view(simplified) :
the thing is that iam iterating through post.all and each post has_many :comments and each comment has comment.description comment.image so how can I get to show the comment for each of the iterated posts is it by another iteration ?
_profile.html.erb :
#posts.each do |x|
<div class="eachpost-wrapper">
<%= x.text %>
<%= x.picture %>
<div class="comments-for-each-post">
<<<<<<<<< the post comments are supposed to be here <<<<<<
</div>
</div>
<% end %>
accounts controller :
def profile
#posts = User.find(params[:id]).posts
#comment = Comment.new
end
comments controller :
def new
#comment = Comment.new
end
def create
#post = Post.find(params[:id])
#comment = #post.comments.new
if #comment.save
redirect_to "success/success"
else
redirect_to 'error/error404'
end
Yes, it is by another iteration. Something along the lines of:
<div class="posts-wrapper">
<% #posts.each do |post| %>
<div class="post-wrapper">
<%= post.text %>
<%= post.picture %>
<div class="comments-wrapper">
<% post.comments.each do |comment| %>
<div class="comment-wrapper">
# do stuff with comment here...
</div>
<% end %>
</div>
<div class="new-comment-wrapper">
# put a new comment form in here...
</div>
</div>
<% end %>
</div>
Keeping in mind what MrYoshiji said about eager loading...

how to hide database information on view?

when I attempt to run my code, I got the error above.
As you can see on the following image, the page posts/index leaves appear some information before the footer of the page :
I don't understand where it may come, because it's the only page where it appeared.
Here's my view :
<%= #post.each do |post| %>
<h1 class="Blog_post_title"><%= link_to post.title, post %></h1>
<p class="date"><%= post.created_at.strftime("%B, %d, %Y") %></p>
<p><%= image_tag post.landing_image.url , class: "landing_image_blog" %></p>
<p><%= post.body %></p>
<%= link_to post do %>
<div class="button12">Continuer la lecture</div>
<% end %>
<div class="border_grey_blog"></div>
<% end %>
</div>
<%= render "footer" %>
my posts_controller.rb:
class PostsController < ApplicationController
def index
#post = Post.all.order('created_at DESC')
end
def new
#post = Post.new
end
def show
#post = Post.find(params[:id])
end
def edit
#post = Post.find(params[:id])
end
def update
#post = Post.find(params[:id])
if #post.update(params[:post].permit(:title,:title2,:title3,:title4,:title5,:title6,:title7,:title8,:title9, :body, :image,:image1,:image2,:image3,:image4,:image5,:image6,:image7,:image8, :landing_image, :some_text1, :some_text2, :some_text3, :some_text4, :some_text5, :some_text6, :some_text7, :some_text8, :some_text9, :some_text0))
redirect_to #post
else
render 'edit'
end
end
def create
#post = Post.new(post_params)
if #post.save
redirect_to #post
else
render 'new'
end
end
def destroy
#post = Post.find(params[:id])
#post.destroy
redirect_to "/posts"
end
private
def post_params
params.require(:post).permit(:title, :body, :image,:image1,:image2,:image3,:image4,:image5,:image6,:image7,:image8, :landing_image, :some_text1, :some_text2, :some_text3, :some_text4, :some_text5, :some_text6, :some_text7, :some_text8, :some_text9, :some_text0, :title2,:title3,:title4,:title5,:title6,:title7,:title8,:title9)
end
end
Any idea ?
Your mistake is in the very first line of the view:
<%= #post.each do |post| %>
should be
<% #post.each do |post| %>
since <%= opens an expression tag that will display its content.
It looks like your outputting the result of #posts.each. Notice how you did this in your view:
<%= #post.each do |post| %>
# other code
<% end %>
This will actually output all the data in the array as a ruby object. If you want to change this to not output everything, you need to change it to
<% #post.each do |post| %>
# other code
<% end %>
This will now not return the #post.each in the html.

Rails 4 - Render controller variable

I'm a Rails newbie and this seems like a trivial thing, but I can't figure out how to render this.
I have a form that takes in a string input:
<%= form_for #idea do |f| %>
<div>
<%= f.label :idea_list %>
<%= f.text_field :idea_list %>
</div>
<%= f.submit %>
<% end %>
And a controller:
class IdeasController < ApplicationController
def index
end
def new
#idea = Idea.new
end
def create
#idea = Idea.new(idea_params)
if #idea.save
render :index
else
render 'new'
end
end
private
def idea_params
params.require(:idea).permit(:idea_list)
end
end
I then want to render the idea_list parameter in index.html.erb, but cannot figure out how to do so. I've tried:
<p><%= #idea %></p>
but I get an output of #<Idea:0x007f8b16d98638>.
<% #idea do |idea| %>
<p><%= idea.idea_list %></p>
<% end %>
I've tried many variations of this but keep getting various errors.
Please help.
So #idea is an instance of an object. idea_list is an attribute. So you need to call #idea.idea_list. Any time you want to reference an instance of an object / model from a controller it's going to #instance.attribute.
In your case, it's going to be
<p><%= #idea.idea_list %></p>
If you want to show them from a list of the all, in your view it's
<%#ideas.each do |idea| %>
<p><% idea.idea_list%></p>
<% end%>
And in your controller it's
def index
#ideas = Idea.all
end

Rails 4 view rendering extra object in view?

I have comments as a subresource of articles, as below:
resources :articles do
resources :comments
end
I want each Article's show page to display all of its corresponding comments, as well as have a form where a user (if signed in) can create a new comment that corresponds with the article.
Here's the show action for ArticlesController:
def show
#comment = #article.comments.build
if user_signed_in?
#comment.user_id = current_user.id
end
respond_with(#article)
end
Here's relevant code from the CommentsController:
before_action :set_article
...
def create
#comment = #article.comments.create(comment_params)
#comment.user_id = current_user.id
if #comment.save
flash[:notice] = "Comment successfully created!"
end
redirect_to #article
end
...
private
def set_article
#article = Article.find(params[:article_id])
end
end
And here's the Article show view:
<b>Post comments:</b><br />
<table>
<thead>
<tr>
<th>User email</th>
<th>Comment</th>
</tr>
</thead>
<tbody>
<% #article.comments.each do |comment| %>
<tr>
<td><%= comment.user.email %></td>
<td><%= comment.body %></td>
</tr>
<% end %>
</tbody>
</table>
<br />
<%= form_for ([#article, #comment]) do |f| %>
<div class="field">
<%= f.text_area :body, placeholder: "Compose new comment..." %>
</div>
<%= f.submit "Post" %>
<% end %>
Here's the two situations I need to fix:
When no user is signed in, the view fails to render because comment.user returns nil
When a user is signed in, a phantom comment for each article appears, because the show action in the ArticlesController is building a new (empty) comment with #comment = #article.comments.build
What is the best way to simultaneously solve both of these problems?
If you don't want to do that in the view, you can do this sort of thing in the controller.
def show
#comment = Comment.new(:article => #article)
respond_with(#article)
end
This won't add the comment to the article.comments array and won't try to render a blank comment.
Do you need to set the user_id on the comment in the form on the show action? If not, you can do this in create
def create
#comment = Comment.new(comment_params)
#comment.article = #article
#comment.user = current_user
if #comment.save
flash[:notice] = "Comment successfully created!"
redirect_to #article
else
render :show
end
end
The benefit to this - you can now handle errors in the form (like if they submit a blank comment, or minimum characters). Even if you handle it in the view with javascript/disabled buttons, it's nice to have the server also support validations and errors.
Just kidding, got it.
Put the build call into the form rather than the ArticleController:
<%= form_for ([#article, #article.comments.build]) do |f| %>
<div class="field">
<%= f.text_area :body, placeholder: "Compose new comment..." %>
</div>
<%= f.submit "Post" %>
<% end %>
and delete everything out of the show action:
def show
respond_with(#article)
end

Resources