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

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 %>

Related

Next/Previous buttons sending to wrong path?

I want previous/next buttons on my edit screen for each record that send you to the previous/next record ordered by id.
None of the simple solutions I have found online have worked and I can't seem to figure out why.
controller:
def edit
#school = School.find(params[:id])
end
model:
def previous_school
School.where(['id < ?', id]).last
end
def next_school
School.where(['id > ?', id]).first
end
view:
<%= link_to("Previous School", #school.previous_school) if #school.previous_school %>
<%= link_to("Next School", #school.next_school) if #school.next_school %>
routes:
get 'school' => 'schools#edit'
When I try pressing the buttons using this code, instead of sending me to where I want to go: "admin/schools/:id/edit", I get sent to: "school.:id" and I'm not sure why.
You'd better use resources for describing routes:
resources :schools
Then your view should be
<%= link_to("Previous School", edit_school_path(#school.previous_school.id) if #school.previous_school %>

How to display all posts with all its comments - 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

rails post path issue

I've an issue with the paths in the views and I don't know how to solve it.
I've "categories" that has_many "posts" and "posts" that belongs_to "categories".
1.- I want to show on home page the truncate last post of an specific category (the ID number "1"). Then I want that post to link to the show post path but I get this error:
"Unknow Action
The action 'index' could not be found for PostsController"
I think I've my paths wrong because I don't need the index view because I'm only going to show that specific post. So, I think that category_posts_path(#last_post) is not the right path (I don't know where to look for more info about making the route path in the views...). Actually, the browser is showing me that is looking for the "2" category when it is a post of the "1" category...? What am I doing wrong?
This is the browser route:
http://localhost:3000/en/categories/2/posts
This is my views/categories/home.html.erb file:
<div class="post_details">
<h2><%= #last_post.title %></h2>
<%= image_tag #last_post.image(:header), class: "post_image" %>
<p><%= truncate #last_post.body, length: 100 %></p>
<p class="button"><%= link_to "READ MORE", category_posts_path(#last_post) %></p>
</div>
2.- I have another path problem in the views/categories/show.html.erb file. I have a loop to show all the post of one specific category, but when I link in some post (to show it) there is the "index" error again:
"Unknow action
The action 'index' could not be found for PostsController"
This is the browser route:
http://localhost:3000/en/categories/1/posts
This is the views/categories/show.html.erb file:
<div class="post_details">
<h2><%= link_to post.title, category_posts_path(post) %></h2>
<%= image_tag post.image(:header), class: "post_image" %>
<p><%= post.body %></p>
</div>
This is the categories_controller.rb file:
class CategoriesController < ApplicationController
before_action :get_categories
def index
end
def show
#category = Category.find(params[:id])
end
def home
if params[:set_locale]
redirect_to root_url(locale: params[:set_locale])
else
#category = Category.find_by_id(1)
#last_post = #category.posts.order("created_at desc").first
end
end
def get_categories
#categories = Category.all.order("rank asc, name asc")
end
end
This is my posts_controller.rb file:
class PostsController < ApplicationController
def show
#category = Category.find(params[:category_id])
#post = #category.posts.find(params[:id])
end
end
This is my route.rb file:
scope '(:locale)' do
resources :categories do
resources :posts
end
resources :contacts
root 'categories#home'
get "/contact" => "contacts#new"
# static pages
get "/investment" => "contents#investment"
get "/partner-with-us" => "contents#partner", as: "partner"
get "/our-companies" => "contents#companies", as: "companies"
get "/site-map" => "contents#sitemap", as: "sitemap"
get "/terms-and-conditions" => "contents#terms", as: "terms"
get "/privacy" => "contents#privacy"
end
When you are nesting routes you should always consider what is the parent and whats a child in given route. Since your paths don't know anything about your associations you have to explicitly define every object in the nesting.
I.e. since you nested posts in categories linking to last post in given category would look like this:
category_post_path(#category, #last_post)
(I think you have also a typo there - category_posts_paths - which links to posts index index - hence the error. Use category_post_path. instead, and give it both parent category and the post.
You can run rake routes to see exact information on paths (or go to http://localhost:3000/rails/info/routes )

How to display latest posted?

So, I have an app that allows users to upload songs and vote them up. The songs with the higher vote count end up on top, and the newly posted songs need to be voted up to be seen (think hackernews).
I also have a 'new songs' page that I'd like to display the newly uploaded songs first negating the votes (alas hackernews)
My current song_controller sorts the songs in the index as such:
def index
#songs = Song.order('plusminus')
end
I have a def new_songs action in the song_controller but I'm not sure how to have it display just the new songs and bypass the thumbs up gem voting.
I don't know much about that gem, but it seems to be scope based. How about just querying the data normally?
def new_songs
#songs = Song.order "id DESC"
end
or better, write your own scope:
# song.rb
scope :newest, order("id DESC")
# song_controller.rb
def new_songs
#songs = Song.newest
end
Pass an instance variable containing the most recently uploaded songs from your controller action to the view:
# app/controllers/songs_controller.rb
def index
#songs = Song.order('plusminus')
#newest_songs = Song.order('created_at DESC').limit(10) # returns the ten most recently uploaded songs
end
In the view, you'll have access to the ten most newest songs via the #newest_songs instance variable:
# app/views/songs/index.html.erb
<h1>Highest Voted Songs</h1>
<% #songs.each do |song| %>
# view logic
<% end %>
<h1>Newest Songs</h1>
<% #newest_songs.each do |song| %>
# view logic
<% end %>
Alternatively, if you want to display the newest songs via an entirely separate view, you could do something akin to the following:
# app/controllers/songs_controller.rb
def new_songs
#songs = Song.order('created_at DESC')
end
# app/views/songs/new_songs.html.erb
<h1>Newest Songs</h1>
<% #newest_songs.each do |song| %>
# view logic
<% end %>
# config/routes.rb
resources :songs do
collection do
get 'new_songs' # creates route from `songs/new_songs` to the `songs#new_songs` controller action
end
end

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 %>

Resources