How to display all posts with all its comments - Ruby on Rails - ruby-on-rails

I'm new to rails and don't know how to achieve this in rails. It might be a really stupid question. But it was not covered in the RoR Codecademy course I did and could not fint a answer elsewhere.
So I have two tables, posts and comments that have an one-to-many relationship. One post has many comments.
I want to display all post with all its comments underneath. What would be the correct way to do this?

There are two ways to do this:
First: you can do like this way in your post controller action (suppose :index) do:
def index
#posts = Post.all
end
And in your index.html.erb
<% #posts.each do |post|%>
# Your post attribute like name etc
<% post.comments.each do |comment|%>
# Your post attribute like name etc
<% end %>
<% end %>
Second: in your post controller action do:
def index
#posts = Post.all.includes(:comments)
end
And in your index.html.erb
<% #posts.each do |post|%>
# Your post attribute like name etc
<% post.comments.each do |comment|%>
# Your post attribute like name etc
<% end %>
<% end %>
Difference in above two ways is that in first one there is always a data base call when you do "post.comments" but in second there is only two data base call i.e. "Post.all.includes(:comments)", no data base call at view part, so it is up to you which way you want to use.

If a Post has_many comments then:
post = Post.find(1)
post.comments.each do |comment|
# do something with each comment here
end

Related

Ruby on Rails 4, How to Display User in Another page

I am new to Ruby on rails. I've created basic demo apps by tutorial learning by examples.
Application have three model User,Village and article
Village has many users, Village has many articles, user and article belongs to village
I work , migration work fine
when iam in http://0.0.0.0:3000/villages/1 , i display all user that belong to village 1
My question is how display in all user in village one this url http://0.0.0.0:3000/villages/1/users
To do that you need to add the url to the routes.rb file under the config folder.
Add line like below
resources :villages do
member do
get '/user', to: 'villages#show'
end
end
I am assuming that your villages show action is the one that has all the user details displayed.
routes.rb
resources :villages do
member do
get :users, :articles
end
end
In villages_controller
def users
#village = Village.find(params[:id])
#values = #village.users.paginate(page: params[:page])
render 'show_data'
end
def articles
#village = Village.find(params[:id])
#values = #village.articles.paginate(page: params[:page])
render 'show_data'
end
In show_data.html.erb
<% if #values.any? %>
<% #values.each do |value| %>
<%= value.name %>
<% end %>
<%end%>
<%= will_paginate %>

Render view from another view : controller not called

I'm developing a litte blog like application and at the moment I'm facing a problem that I can't resolve.
I have 2 models at the moment :
1. Post
2. Comment
I can already manage my posts without difficulties but I have some problems with comments. I chose to make a relation has_many / belongs_to between my post and my comment models. I'd like to display all the comments related to a post when the user is on the post's page. My erb looks like this :
#some code
#...
#...
#render the comments
<%= render :template => "comments/index", :locals => {:post_id => #post.id} %>
My problem here is that the method index from my CommentsController is never called. I put some puts in the index method and they are never displayed in the console.
Should I use another tag to render the view ? Is there another way to do this ?
Thanks in advance for your help.
If the post view is the only page to show comments, you don't have to call comments/index to get comments, just show comments when rendering the post view, for example
In your post view
#some code
#...
# render comments
<% #post.comments.each do |c| %>
<%= c.content%>
# ...
<% end %>
Or put them in a partial with a post parameter if comments are used in many views
In app/views/partials/_comments.html.erb
# render comments
<% post.comments.each do |c| %>
<%= c.content%>
# ...
<% end %>
and render this partial where you want to show comments:
#some code
#...
# render comments
<%= render partial: "partials/comments", locals: { post: #post } %>
Using comments/index to get comments and showing them in a view is more likely the frondend tech such as Javascript/AJAX to load page parts dynamically. In this case, the comments/index is more likely an API call(render a JSON format instead of a html view).

What is the proper "RESTFUL" way to list all posts

I am trying to figure out the proper restful way of displaying all posts from all users.
I have an application with a user and post resource. The post resource is nested in the users. Now I am trying to sort of display a feed of all posts and with the name of the user who posted them.
I cant quite figure out where this feed should be placed. And in view file, how to get post user names.
in controller:
#posts = Post.all(:include => "user")
in view:
<% #posts.each do |post| %>
...
some html here
...
<%= post.user.name %>
<% end %>
Pay attention to "include" word. It means that users information will be got with posts with 1 query to Database.
To better understand it you can read this
You can create a route for displaying all posts by:
routes.rb
get "posts" => "posts#index"
This will create a route http://yourdomain.com/posts that will show all posts. Then make sure you have an action for index to show all of the posts.
posts_controller.rb
class PostsController < ApplicationController
def index
#posts = Post.all(:include => "user")
end
end
Make sure your model associations are set up properly.
user.rb
has_many :posts
post.rb
belongs_to :user
# This assumes you have a column on your table for user_id which I assume you do since you mentioned your nested resource already.
You view would simply show the user's name associated with each post.
views/posts/index.rb
<% #posts.each do |post| %>
post.user.name
<% end %>

Kaminari: paginate a scoped model. Controller/View responsibility

I'm not sure i've entitled the question correctly.
In my project I have a categories controller with show action
def show
#category = Category.find params[:id]
end
And in my view I render all the posts associated with this category
#category.posts.each do |post|
link_to post.title, post
So now I want to add pagination with kaminari.
I believe I could just change #category.posts.each to #category.posts.page(params[:page]).each, but I also think that this should be responsibility of the controller. Or am I wrong? Maybe it's totally fine?
Thanks everyone.
Your show method should look like this:
def show
#posts = Category.find(params[:id]).posts.page(params[:page])
end
And in view:
#posts.each do |post|

undefined method 'each' Ruby on Rails

Apologies in advance, I am a newbie trying to get my head around rails.
My View at the bottom works when I use:
def show
#posts = Post.all
end
However in my controller I now have:
def show
#posts = Post.find_by_category_id params[:id];
end
In my view I have
<%= #posts.each do |post| %>
<%= post.title %>
<% end %>
Some please explain why I get this error. What should I use. category_id is a foreign key on the Post table.
Look at http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-find_by
Finds the first record matching the specified conditions
find_by_ will return only one post, not a collection. So you are not able to use each.
try
def show
#posts = Post.all.find_by_category_id params[:id];
end

Resources