Good day all,
Can someone kindly assist me with nested resources and its best practice.
I would like to restrict my :events route to only :show and :index, is this the correct way of doing it?
resources :events do
resources :registrations, :except => [:index]
end
resources :events, :only => [:index, :show]
Is this the best way or the way more Rubyist would handle such thing? I've added two lines of resources :events or is there a way to combine it all in 1 block?
Thanks in advance.
Yes. You can combine it in one block like:
resources :events, only: [:index, :show] do
resources :registrations, except: :index
end
Related
I've three models Project, Card and Task.
project has_many :cards
card has_many :tasks
I've defined the route for building cards like following:
resources :projects, except: [:new, :edit, :show] do
resources :cards do
resources :tasks
end
end
It'll create path for cards as: projects/:project_id/cards/
It'll create path for tasks as: projects/:project_id/cards/:card_id/tasks
What I need is:
Card routes should be nested to Project. (which I currently have) and Task routes should nested to only Card like /cards/:card_id/tasks (which I need).
How can I achieve that?
Thanks in advance!
resources :projects, except: [:new, :edit, :show] do
resources :cards
end
resources :cards do
resources :tasks
end
This is what you are looking for
You can just do,
resources :projects, except: [:new, :edit, :show] do
resources :cards
end
And further try with defining each route for task by,
get '/cards/:card_id/tasks', to: 'tasks#index'
I did not test but should work, Sad is you have to define it for each specific route.
I have following relationship routes:
resources :courses, only: [:index, :show] do
resources :enrols, only: [:new, :create]
resources :lectures, only: [:show]
end
resources :code_casts, :path => 'casts', :as => 'casts', only: [:index, :show]
resources :blogs, :path => 'blog', :as => 'blog', only: [:index, :show] do
resources :blog_votes, only: [:create, :destroy]
end
I want polymorphic comments in courses, lectures, code_casts and blog.
Problem is lecture has a parent of course so route will be course/course_id/lecture/id and blog path will blog/id where comments will have different show pages.
If I understand the problem correctly, there is nothing special about deeply nested resources. So you might need something like this
# routes.rb
concern :commentable do
resources :comments
end
resources :courses, only: [:index, :show] do
resources :enrols, only: [:new, :create]
resources :lectures, only: [:show], concerns: [:commentable]
end
resources :code_casts, :path => 'casts', :as => 'casts', only: [:index, :show]
resources :blogs, :path => 'blog', :as => 'blog', only: [:index, :show], concerns: [:commentable] do
resources :blog_votes, only: [:create, :destroy]
end
This will create nested comments resources for lectures and blogs.
Than you need to differentiate the path in a comments controller
# comments_controller
def create
Comment.create(commentable: commentable, other_params...) # assuming you have `commentable` polymorphic belongs_to
end
# a little more ugly than Ryan suggests
def commentable
if request.path.include?('blog') # be careful. any path with 'blog' in it will match
Blog.find(params[:id])
elsif params[:course_id] && request.path.include?('lecture')
Course.find(params[:course_id).leactures.find(params[:id]) # assuming Course has_many lectures
else
fail 'unnable to determine commentable type'
end
end
All 'magic' is in commentable method, where youare checking the path and determine which commentable object to pick. I use similar approach, but this exact code is written by memory without testing. Hopefully you've got the idea.
How do I add the /search endpoint to all these resources in one go?
MyCoolApp::Application.routes.draw do
resources :posts, only [:index, :show, :create] do
collection { get :search }
end
resources :authors, only [:index, :show] do
collection { get :search }
end
resources :comments, only: [:index, :show] do
collection { get :search }
end
resources :categories, only: [:index, :show] do
collection { get :search }
end
resources :tags, only: [:index] do
collection { get :search }
end
end
I saw this answer which is close, but I need to be able to specify the actions for reach resource. Is there a better way to inject the search route in a better way?
%w(one two three four etc).each do |r|
resources r do
collection do
post 'common_action'
end
end
end
Something like this?
resources :posts, only [:index, :show, :create, :search]
I know you've tagged this question ruby-on-rails-3, but I'm going to provide the Rails 4 solution for anyone who comes across this in the future.
Rails 4 introduces Routing Concerns
concern :searchable do
collection do
get :search
end
end
resources :posts, only [:index, :show, :create], concerns: [:searchable]
resources :authors, only [:index, :show], concerns: [:searchable]
resources :comments, only: [:index, :show], concerns: [:searchable]
resources :categories, only: [:index, :show], concerns: [:searchable]
resources :tags, only: [:index], concerns: [:searchable]
I've setup a simple app and added a scaffold to do some of the work for me (I'm a noob).
resources :cars
How do I remove certain actions from the routes? And remove the corresponding urls?
For example I want to keep the 'show' and 'edit' actions & urls.
But I don't want there to be a 'new' 'index' or 'delete'
I understand this is probably a really simple question, but I've not been able to find an answer.
resources :cars, :except => [:new, :index, :delete]
or
resources :cars, :only => [:show, :edit]
Also take a look at Rails Guides
If you want to remove some actions then you can mention action name in the array
resources :photos, only: [:index, :show]
But
if you want to disable all the default CRUD actions then you should use
resources :photos, only: []
In my routes.rb I have:
resources :countries do
resources :cities
end
But I only want:
new: GET /countries/:id/cities/new
create: POST /countries/:id/cities
And not the 7 actions.
What can I do?
Here you go:
resources :cities, :only => [:new, :create]
Reference here.
try
resources :cities, :only => [:new,:create]