I'm another Rails newbie and have followed the Ruby tutorial on creating a blog.
Each post has many comments and the comments belong to the posts.
I can see the comments in the individual blogs and have created a show link to show the individual comment.
What I'd really like to do is create an index page for comments which shows all of them. I created an index action in the comments controller:
def index
#title = "All comments"
#comments = Comment.all
end
And an accompanying index page,
All comments
<% #comments.each do |comment| %>
Comment: <%= #comment.body %>
<% end %>
But I get an error:
undefined method `body' for nil:NilClass
My routes file:
resources :posts do
resources :comments
end
I'd really appreciate it if someone could point me in the right direction - I think my issue is that my comments are nested in the posts.
Thanks,
Bob
You should be using the comment passed into the block:
<% #comments.each do |comment| %> Comment: <%= comment.body %>
You're currently calling #comment.body, and #comment is nil because it is undefined in your controller and elsewhere.
So in your loop in the view file, you are iterating over the #comments array, creating a comment object for each of the comments in #comments. As such, try
<% #comments.each do |comment| %> Comment: <%= comment.body %>
Related
I'd like to make a list of posts on the app/views/posts/show.html.erb page and sort each by id.
Similar to how all of the posts are listed on my app/views/posts/index.html.erb page using the code block below:
<% #posts.each do |post| %>
<div class="col-md-4">
<%= image_tag post.img %>
<h1><%= post.title %></h1>
<p><%= post.content %></p>
<br>
<%= link_to 'Read More', post_path(post) %>
</div>
<% end %>
When I try to use the same each do method on the show page I get an error. But this is what I currently have (it only displays an img/link to the current post):
<h1>Recent Posts</h1>
<ul>
<li>
<%= image_tag #post.img %>
<h2>
<%= link_to #post.title %>
</h2>
</li>
</ul>
Index is for displaying all the items of x.
def index
#posts = Post.all
end
So what you are doing is taking all your posts, and putting them in an array called #posts. You can iterate or enumerate over those with .each do |x|. That means go through each object in the array and show the post image, title and content.
You didn't display your show, but typically a show looks like:
def show
#post = Post.find(params[:id])
end
So you are finding the post with :id and storing that data in #post. This is only 1 object, it's not an array. That's why your .each do |x| isn't working.
There is nothing stopping you from making
def show
#posts = Post.all
end
But then you can't take advantage of rails shortcuts and are repeating yourself, which isn't good in programming. If you want two very distinct windows that use the same information, it's better to figure that out in html/css with a bit of javascript.
The show action of your PostsController is probably only setting up #post, and not #posts. You can't use .each with #post because it's an instance of Post, and not an array, or something that responds to .each. Look at how #posts is set up in the index action, and copy that to your show action.
Im trying to link_to the show action for a post.
In my controller I have:
#post = Post.all
In my view I'm trying to link it to the last post like this:
<%= link_to #post.last do %>
<%= #post.last.title %>
<% end %>
But it does not take me to the show page for that post?
Post.all loads all posts, but does not guarantee an order. You might want to use the id or the created_at value to order your list of posts:
# in your controller
#posts = Post.order(:id)
# in the view:
<%= link_to #posts.last.title, #posts.last %>
Or - if you don't need the other posts in the view - just load the lastest post:
# in the controller:
#latest_post = Post.order(:id).last
# in the view:
<%= link_to #latest_post.title, #latest_post %>
Try with below code,
<%= link_to post_path(#post.last) do %>
<%= #post.last.title %>
<% end %>
If this code not work then please find route with fire rake routes in your terminal and replace post_path with your routes
Hope this will work.
On my index page, I'm listing all the posts from all the blogs. How would I link_to from a post that has a blog_id to that actual blog.
I could easily in a controller do #blog = Blog.find(#posts.blog_id) if it were just one blog, but since it's not and I already have the blog_id for the post blog, I feel there has to be a way to do something like:
<% #posts.each do |f| %>
<%= f.title %>
#<%= link_to "Blog", go to the Blog using f.blog_id somehow? %>
<% end %>
The answer was given in a comment from "BroiStatse" and I thought I'd give the answer to it since he answered it in the comments section.
Basically had to do this simple line:
link_to 'Blog', blog_path(f.blog_id)
I'm trying to display the images of the users who've upvoted a post using the acts_as_votable gem, exactly like this question. The problem is the answer that worked for that question is not working in my case.
I display the upvotes count like this:
<%= #post.cached_votes_total %>
I've added 'acts_as_votable' and 'acts_as_voter' into the post and user models.
The controller:
def upvote
#post = Post.find params[:id]
#post.liked_by current_user
end
The accepted answer in the above question is this:
<% #post.votes_for.voters.each do |p| %>
<%= image_tag(p.image) %>
<% end %>
However this gives me an 'undefined method `votes_for' ' error.
<% #post.votes.each do |user| %>
<%= user %>
<% end %>
This gives no error but I can't access the user's image.
Ok, I got it by playing around a bit more.
<% #post.votes.by_type(User).voters.each do |user| %>
I am trying to add a featured post feature to my Ruby on Rails Blog. So far I have added a featured_post column to my post table and it passes a 1 if the check box is selected and 0 if not.
Now I am attempting to pull out these posts by doing the following:
/views/posts/index.html.erb
<% #featured_post.each do |post| %>
<%= post.title %>
<% end %>
And in the posts_controller.rb I am doing the following in the index action:
#featured_post = Post.all
Obviously this brings in all the post titles which is not what I want. I am assuming I have to add something to the controller to all for this but not sure what that is.
In your post model, write this
named_scope :featured,:conditions => {:featured_post => true }
write this in your controller
#featured_posts = Post.featured
and in view use this,
<% #featured_posts.each do |post| %>
<%= post.title %>
<% end %>
now you should get all the featured posts.