why rails is making a path like
/notification_templates/duplicate_me.1
it is supposed to be
/notification_templates/duplicate_me/1
my routes are
resources :notification_templates do
collection do
get :blast_send
patch :deactivate
patch :activate
get :get_list
post :duplicate_me
end
end
and my link is
<%= link_to "Duplicate", duplicate_me_notification_templates_path(template), method: :post, class: "btn btn-primary" %>
You are trying to pass a resource to a collection route. For this to work, your route should be defined as a member route instead:
resources :notification_templates do
collection do
get :blast_send
patch :deactivate
patch :activate
get :get_list
end
member do
post :duplicate_me
end
end
And the reason it translates the route to a dot currently is that the path helper most probably understands the parameter passed in (template) as a format specification. Formats are separated from the route using a dot.
Since the route is made for collection, it does not expect a template instance variable for id.
To make the route as /notification_templates/duplicate_me/1, make the changes in your routes.rb like
resources :notification_templates do
collection do
get :blast_send
patch :deactivate
patch :activate
get :get_list
end
post :duplicate_me, on: :member
end
and change your view to
<%= link_to "Duplicate", duplicate_me_notification_template_path(template), method: :post, class: "btn btn-primary" %>
When you want to pass id like
/notification_templates/duplicate_me/1
as member for the resource you should make member routes. Please look in this enter link description here . it would help you.
This way would help you.
resources :notification_templates do
collection do
get :blast_send
patch :deactivate
patch :activate
get :get_list
end
member do
post :duplicate_me
end
end
Related
I am using destroy
In my view, I have:
#delete_archive_modal.modal.fade
.modal-header
%h3
%i.icon-exclamation-sign
Attention
.modal-body
%p= "Are you sure you want to delete this portal?"
.modal-footer
%a.btn{"data-dismiss" => "modal", :href => "#"} Cancel
= link_to 'Delete', delete_portal_path(portal)
Routes:
resources :portals do
resources :pill_tabs, only: [:show, :edit]
resources :page_urls do
collection do
get :redirects
end
end
resources :zero_touch_configs do
member do
get :history
end
end
member do
get :navigation
get :history
get :sitemap
get :url_list
post :generate_sitemap
post :add_modules
post :archive
post :delete
end
collection do
get :index, path: '/'
get :new, path: '/new(/:portal_type)'
get :accessible_sites
get :archive_index
get :delete
end
And in my controller:
def destroy
#portal = Portal.find(params[:id])
#portal.destroy
flash[:notice] = 'Portal deleted successfully.'
redirect_to action: :archive_index
end
routes:
portals GET /portals(.:format) portals#index
GET /portals/new(/:portal_type)(.:format) portals#new
accessible_sites_portals GET /portals/accessible_sites(.:format) portals#accessible_sites
archive_index_portals GET /portals/archive_index(.:format) portals#archive_index
delete_portals GET /portals/delete(.:format) portals#delete
history_portal_stack_wrapper GET /portals/:portal_id/stack_wrappers/:id/history(.:format) stack_wrappers#history
drafts_portal_stack_wrapper GET /portals/:portal_id/stack_wrappers/:id/drafts(.:format) stack_wrappers#drafts
purge_portal_stack_wrapper GET /portals/:portal_id/stack_wrappers/:id/purge(.:format) stack_wrappers#purge
all_drafts_portal_stack_wrappers GET /portals/:portal_id/stack_wrappers/drafts(.:format) stack_wrappers#all_drafts
portal_stack_wrappers GET /portals/:portal_id/stack_wrappers(.:format) stack_wrappers#index
POST /portals/:portal_id/stack_wrappers(.:format) stack_wrappers#create
new_portal_stack_wrapper GET /portals/:portal_id/stack_wrappers/new(.:format) stack_wrappers#new
edit_portal_stack_wrapper GET /portals/:portal_id/stack_wrappers/:id/edit(.:format) stack_wrappers#edit
portal_stack_wrapper GET /portals/:portal_id/stack_wrappers/:id(.:format) stack_wrappers#show
PATCH /portals/:portal_id/stack_wrappers/:id(.:format) stack_wrappers#update
PUT /portals/:portal_id/stack_wrappers/:id(.:format) stack_wrappers#update
DELETE /portals/:portal_id/stack_wrappers/:id(.:format) stack_wrappers#destroy
history_portal_config_bundle GET /portals/:portal_id/config_bundles/:id/history(.:format) config_bundles#history
portal_config_bundles GET /portals/:portal_id/config_bundles(.:format) config_bundles#index
POST /portals/:portal_id/config_bundles(.:format) config_bundles#create
new_portal_config_bundle GET /portals/:portal_id/config_bundles/new(.:format) config_bundles#new
edit_portal_config_bundle GET /portals/:portal_id/config_bundles/:id/edit(.:format) config_bundles#edit
portal_config_bundle GET /portals/:portal_id/config_bundles/:id(.:format)
But I am getting a routing error and don't know where to go from here...
No route matches [GET] "/portals/asdg/delete"
Can anyone share a guide or point me to documentation that helps me understand what's wrong here?
Try
= link_to 'Delete', portal_path(portal), method: :delete
Here are the all 7 routes for portal
portals GET /portals(.:format) portals#index
POST /portals(.:format) portals#create
new_portal GET /portals/new(.:format) portals#new
edit_portal GET /portals/:id/edit(.:format) portals#edit
portal GET /portals/:id(.:format) portals#show
PATCH /portals/:id(.:format) portals#update
PUT /portals/:id(.:format) portals#update
DELETE /portals/:id(.:format) portals#destroy
And in your routes you have delete_portal path will exist because of
member do
post :delete
end
If you want to call this then you have do define method for this action in your controller and call this path with method: :post
But in RESTful routes delete action have always DELETE method, see in above routes.
There are two issues in your link_to tag.
You used delete_portal_path(portal) but if you run rake routes on your console you will see no such route exist. it have portal_path(portal).
You need to specify method type in route in case of Show(GET default), update(PUT) and delete(DELETE). Because all share same path portal_path(portal).
So your final route should be:
= link_to 'Delete', portal_path(portal), method: :delete
More detail here
You need to define http method when you use delete
= link_to 'Delete', portal_path(portal), method: :delete
It will work.
In the following code segment
.comment
%p= comment.comment
%p= comment.user.email
= link_to 'Edit', edit_post_comment_path(comment.post, comment)
= link_to "Delete", [comment.post, comment], method: :delete, data: {confirm: 'Are you sure"'}
why do both Edit and Delete take in comment.post as a parameter? What does it mean?
It require comment.post because you have made nested routes, check your routes.rb file where you have define routes as below:
resources :posts do
resources :comments
end
and your routes is for EDIT and DELETE is
edit_post_comment GET /posts/:post_id/comments/:id/edit(.:format) comments#edit
DELETE /posts/:post_id/comments/:id(.:format) comments#destroy
That's why you always need to pass comment.post as a parameter.
If you don't want comment.post as parameter you can change your routes as:
resources :posts
resources :comments
OR if you don,t want to pass comment.id in any particular action do your routes as
resources :posts do
resources :comments, :except => [:delete]
end
resources :comments, :only => [:delete]
NOTE: I am assuming that you don't want comment.post parameter for :delete action
Comment is a nested resource here which means comments belongs to a post.
Because rails routes are defined in a RESTFUL Way.
If you see in the RESTful way, all the CRUD operations in comment resource require post resource id, since comment is associated with post.
Not only the 'Edit' and 'Delete' operation requires parent resource id, All the CRUD operation requires it.
Have a look here at Nested resource section.
i try to fill twice id in url, but when i send params twice id just one id fill the url id.
My route :
namespace :admin do
resources :stores
get "/:id/new_items"=> 'stores#new_items', as: :store_new_items
post "/:id/create_items"=> 'stores#create_items', as: :store_create_items
get "/:id/show_items/:id"=> 'stores#show_items', as: :store_show_items
get "/:id/items/:id/new_items_sub" => 'stores#new_items_sub', as: :store_new_items_sub
post "/:id/items/:id/create_items_sub" => 'stores#create_items_sub', as: :store_create_items_sub
get "/:id/items/:id/show_items_sub/:id" => 'stores#show_items_sub', as: :store_show_items_sub
end
my view :
<%= link_to "add new items", admin_store_new_items_sub_path(#store.id, #items.id), :class=> "btn" %>
i hope my url like this :
http://localhost:3000/admin/#{store.id}/items/#{items.id}/new_items_sub
but i get same id like this :
http://localhost:3000/admin/#{store.id}/items/#{store.id}/new_items_sub
please tell me when i'm wrong? thanks
you have to create neseted routes for that .have a look at
http://guides.rubyonrails.org/routing.html#nested-resources
for example
resources :publishers do
resources :magazines do
resources :photos
end
end
will accept routes /publishers/1/magazines/2/photos/3
Your params should be unique, so you can't pass more than one different :id params. Instead. you can do something like:
get '/:store_id/show_items/:id', as: :store_show_items
and in view:
<%= link_to 'show items', store_show_items_path(#store.id, #item.id) %>
Also, you should read more about Resources and Nested Resources in Rails, there's probably no need to complicate your life by creating each route independently.
You could refactor this to use nested routes like this (you may have to change controller method names):
namespace :admin do
resources :stores do
resources :items, :only => [:new, :create, :show] do
resources :subs, :only => [:new, :create, :show]
end
end
end
This would give you a few url helpers like this: new_store_item_sub_path(#store.id, #item.id) for the new action and store_item_sub_path(#store.id, #item.id, #sub.id) for the show action.
Run rake routes to see what helpers and routes you have access to.
Have a look here to find out more about nested routes.
Your code can be DRYed up significantly. Hopefully this works; might need some tweaking:
namespace :admin do
resources :stores do
member do
get :new_items, as: :store_new_items
post :create_items, as: :store_create_items
end
get "show_items/:id"=> 'stores#show_items', as: :store_show_items
resources :items do
get :new_items_stub => 'stores#new_items_sub', as: :store_new_items_sub
post :create_items_stub => 'stores#create_items_sub', as: :store_create_items_sub
get "show_items_sub/:id" => 'stores#show_items_sub', as: :store_show_items_sub
end
end
end
Uses Member Routes (see 2.10) & Nested Resources
Nested Resources
The crux of your issue is that you're trying to pass the :id param twice
Fortunately, Rails has a solution to this, in the form of Nested Resources. These work by taking the "parent" id and prepending a singular prefix, such as :store_id, allowing you to use the :id param for another set of methods
I'm trying to call a custom controller action shuffle for a resource that is nested within another resource. I can't seem to get the method call right.
routes.rb
resources :templates do
resources :items
end
match "/templates/:template_id/items/shuffle" => "items#shuffle"
I have a link in my items#index view:
<%= link_to 'Shuffle', shuffle_template_items_path(#template) %>
When I click on the link, I get the following error:
undefined method `shuffle_template_items_path' for #<#<Class:0x42577c8>:0x3e77578>
I have also tried <%= link_to 'Shuffle', template_items_shuffle_path(#template) %> and that did not work.
How do I correctly call this custom action?
You probably want this:
resources :templates do
resources :items do
get :shuffle, :on => :collection
end
end
If you want your custom action to have a name, you need to provide it:
match "/templates/:template_id/items/shuffle" => "items#shuffle", :as => :suffle_template_items
I think the best way to write shuffle is in collection as per the documentation of Rails Routes:
So it would looks like this:
resources :templates do
resources :items do
collection do
get :shuffle
end
end
end
when you try rake routes you will find shuffle_template_items GET /templates/:template_id/items/shuffle(.:format) items#shuffle.
I have Exam controller.
In routes.rb there is "resources :exams"
In controller there are REST-like generated methods.
I want to add my own method there:
def search
#exams = Exam.where("name like ?", params[:q])
end
In view file:
<%= form_tag(search_path, :method => "post") do %>
<%= label_tag(:q, "Szukaj: ") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Szukaj") %>
<% end %>
I know, there is no results presentation yet, it doesn't work at all at this moment (:
When i go to http://localhost:3000/exams/search it's mapping it to show controller and search is a :id paramether then...
How to get http://localhost:3000/exams/search to run the seach controller?
You forgot to add route. Put this in routes.rb, before resources :exams
map.search '/exams/search', :controller => :exams, :action => :search
Note, that resources :exams doesn't generate routes for all public methods of the controller, it generates very specific set of routes. You can find more information in the rails routing guide. (see section 3.2 in particular)
You'll need to add additional parameters to your mapping. You can add "collection" methods like so:
map.resources :exams, :collection => {:search => :get}
When you rake routes, you'll see that it generates something like so:
search_exams GET /exams/search(.:format) {:controller=>"exams", :action=>"search"}
exams GET /exams(.:format) {:controller=>"exams", :action=>"index"}
POST /exams(.:format) {:controller=>"exams", :action=>"create"}
new_exam GET /exams/new(.:format) {:controller=>"exams", :action=>"new"}
edit_exam GET /exams/:id/edit(.:format) {:controller=>"exams", :action=>"edit"}
exam GET /exams/:id(.:format) {:controller=>"exams", :action=>"show"}
PUT /exams/:id(.:format) {:controller=>"exams", :action=>"update"}
DELETE /exams/:id(.:format) {:controller=>"exams", :action=>"destroy"}