Rails RESTful URL's: All Posts under certain Category - ruby-on-rails

Currently I use my posts#index action to show all posts or filter'em by category in case its specified:
PostsController:
def index
#posts = Post.all(:order => "created_at DESC")
#posts = #posts.by_category(params[:category_id]) #Custom named_scope
end
Routes:
map.connect '/post/by_category/:category_id', :controller => :posts, :action => :index
map.resources :users
So /posts will return all the posts, and /posts/by_category/1 will return all posts under category 1
I wonder if there is a way of doing it more RESTful, and maybe to get some pretty url_paths.
I've read the guides (Using latest 2.3 Rails branch) but neither nested routes nor collections seemed appropiate for this case. Thanks :)

resources :posts
resources :categories do |categories|
categories.resources :posts
end
Your urls then:
/posts - all posts
/posts/:id -certain post
/categories - all categories
/categories/:id - certain category
/categories/:id/posts - all posts within a certain category.

Related

Showing index view for all categories in a survey

In rails, I have two models, survey and category. Survey has_many categories and category belongs_to survey. I have an index page showing all of my surveys, and I want a button that directs the user to a view that shows an index of all of the categories for each individual survey. So basically I want them to click on the button and go to something like /surveys/:id/categories. How would I go about doing this?
First define the routes:
# config routes.rb
resources :surveys, only: [:index] do
resources :categories, only: [:index]
end
Using resources gives us nice restful routes:
$ rake routes
Prefix Verb URI Pattern Controller#Action
survey_categories GET /surveys/:survey_id/categories(.:format) categories#index
surveys GET /surveys(.:format)
Checkout the prefix column - this means that we can get a path to the categories by survey_categories_path(survey_id: #survey.to_param).
We then need a controller for categories:
class CategoriesController < ApplicationController
def index
# We use eager_load to get survey and categories in one DB query
#survey = Survey.eager_load(:categories).find(params[:survey_id])
#categories = #survey.categories
end
end
Something like:
routes.rb
...
get 'surveys/:id/categories', :to => 'categories#index'
...
categories_controller:
...
def index
#categories = Survey.find(params[:id]).categories
end
...

Model Association

Hi I have a little problem with associations, I'm working with Rails 3.2, I want to create a special blog, this blog has many sections and this sections has many articles and an article belongs to a Category. So my models are:
class Article < ActiveRecord::Base
belongs_to :section
belongs_to :category
class Category < ActiveRecord::Base
has_many :articles
class Section < ActiveRecord::Base
has_many :article
So articles belongs_to section, in routes.rb :
resources :sections do
resources :articles
end
Rake Routes:
POST /sections/:section_id/articles(.:format) articles#create
new_section_article GET /sections/:section_id/articles/new(.:format) articles#new
edit_section_article GET /sections/:section_id/articles/:id/edit(.:format) articles#edit
section_article GET /sections/:section_id/articles/:id(.:format) articles#show
PUT /sections/:section_id/articles/:id(.:format) articles#update
DELETE /sections/:section_id/articles/:id(.:format) articles#destroy
sections GET /sections(.:format) sections#index
POST /sections(.:format) sections#create
new_section GET /sections/new(.:format) sections#new
edit_section GET /sections/:id/edit(.:format) sections#edit
section GET /sections/:id(.:format) sections#show
PUT /sections/:id(.:format) sections#update
DELETE /sections/:id(.:format) sections#destroy
So my question is How do I create a Categories_controller with index and show action.
to show the articles that belongs to that category, and have a link_to in views(Category#show) for the articles path.
Assuming that you do need nested routes to fit your domain model (ex. articles need to display differently based on whether they are being viewed in the context of a category or a section), then you can just create another set of nested routes like so:
routes.rb
resources :categories, only: [:index, :show] do
resources :articles
end
That will set up routes to find your categories and articles by categories, but you will have to fork your logic in your ArticlesController on params[:category_id] or params[:section_id] like so:
class ArticlesController < ApplicationController
def index
if params[:section_id]
# handle section_articles_path to display articles by section
elsif params[:category_id]
# handle category_articles_path to display articles by category
else
# handle articles_path to display all articles (assuming you have resources :articles in routes)
end
end
# ...
end
The link to show an article based on a category will then use the generated route helper methods created for you.
categories/show.html.erb
<ul>
<% #category.articles.each do |article| %>
<li><%= link_to article.title, category_article_path(#category, article) %></li>
<% end %>
</ul>
You could then, of course, refactor the view code to render the collection as its own partial rather than manually iterating, but I'll leave it at that for now...
If you don't need to handle the context differently (accessing an article through a section versus a category), I'd recommend just setting up three basic routes (:articles, :sections, :categories) and going from there.
It's Very much simple
match 'catagories' => "catagories#index" and match 'catagories/show/:id' => "catagories#show"
In show action #articles = Article.where("category_id",params[:id])
#articles = Article.where("category_id",params[:id]) This will solve your purpose

Resourceful Routes helpers _path and _url dont work

I am trying to redirect user to show_city_url or show_city_path but i get an exception that they are both undefined.In the city controller i have three actions show,like, and dislike. unlike_city_path and like_city_path works but show_city_path doesnt.Also when i put this in all_cities action redirect_to :controller=>"city",:action=>"show" works.What am i doing wrong?Thank you.
class HomeController < ApplicationController
def all-cities
redirect_to show_city_url
end
end
In the Routes
resources :city do
member do
post :like
post :dislike
get :show
end
end
according to your comments:
resources :cities, :controller => 'city' do
collection do
get :show, :as => :show
end
member do
post :like
post :dislike
end
end
now you can call show_cities_url and you'll land in the show action of your CityController.
PS: Following the Rails' convention makes your life easier ;)
RoR Guide: Rails Routing from the Outside In

Rails - Routes for Nested Resources

I have a conversations controller and a comments controller.
What I would like to do is have the following (from the logs):
Started POST "/conversations/217/comment_beta" for 127.0.0.1
Post the Comments Controller not the Conversations Controller which is what Rails is trying to do now:
AbstractController::ActionNotFound (The action 'comment_beta' could not be found for ConversationsController):
Here is my routes file:
resources :conversations do
resources :comments, :only => [:create, :update,:destroy, :comment_beta], :constraint => {:context_type => "conversations"} do
collection do
post 'comment_beta'
end
end
collection do
get 'read_updater'
end
end
Suggestions? Thanks
your rails routes is actually doing what it is supposed to do. if you conversations/:id/comment_beta to go to your comments controller, either you should change your routes via match or go to the correct url which is /conversations/:id/comments/:comment_id/comment_beta
If you're posting to create a new comment, why aren't you using RESTful routes?
resources :conversations do
resources :comments do
collection do
post 'comment_beta'
end
end
end
should give you /conversations/:id/comments/comment_beta
collection because you don't need an id

How to route to different actions depending on the request method in Rails?

As we all know, a simple
resources :meetings
will generate 7 actions for me. Two of these are index and create. A really cool thing about these two!: The URL for both is /meetings, but when I GET /meetings I am routed to the def index action and when I POST /meetings, I am routed to the def create action. Nice.
Now I want to do this:
resources :meetings do
member do
get 'scores'
post 'scores'
end
end
And, you guessed it!, I want them to route to different actions in MeetingsController: GETting /meetings/1/scores will route to def scores and POSTing to meetings/1/scores will route to def create_scores.
Try:
resources :meetings do
member do
get 'scores' => :scores
post 'scores' => :create_scores
end
end
I suppose you will be also interested in having named routes:
resources :meetings do
member do
get 'scores' => :scores, :as => 'scores_of'
post 'scores' => :create_scores, :as => 'create_scores_of'
end
end
Then you get scores_of_meeting_path and create_scores_of_meeting_path helpers.
Above may be DRYed more with:
get :scores, :as => 'scores_of'
Define the routes such as this:
resources :meetings do
member do
get 'scores', :action => "scores"
post 'scores', :action => "post_scores"
end
end
But it sounds to me like it would be much easier to create another controller to handle this, as scores to me feels like another resource entirely, even if they don't have their own model association.
Ha! Never underestimate the ability of asking a question well to lead you to its answer.
resources :meetings do
member do
get 'scores', :to => "meetings#scores"
post 'scores', :to => "meetings#create_scores"
end
end

Resources