trouble getting route to work in Rails - ruby-on-rails

I have the following in my routes.rb:
resources :resources
match "/resources/:category" => 'resources#index', :as => :resources
In my index.html.erb I have the following:L
<% #categories.each do |category| %>
<li class="active">
<%= link_to category.name, resour_path(:category=>category.name.parameterize), :class => "large", remote => true %>
</li>
<% end %>
I want to submit to the index action of the ResourcesController because I want to show different items on the page as in filter.
The links currently are giving an error as they are calling the show action and not going to the index action.
How can I get them to submit to the index action of the routes controller?

The line match "/resources/:category" is never reached when going for the route. The path /resources/some-category is matched by resources :resources, and some-category is considered the id for the show action.
Option 1
Switch the lines so the match line is matched first.
match "/resources/:category" => 'resources#index', :as => :resources
resources :resources
Option 2
Turn
resources :resources
into
resources :resources, :except => :show
References
As described in http://guides.rubyonrails.org/routing.html:
Rails routes are matched in the order they are specified, so if you have a resources :photos above a get 'photos/poll' the show action’s route for the resources line will be matched before the get line. To fix this, move the get line above the resources line so that it is matched first.

Related

Rails[Devise]: devise breaking navbar links

I have a Bootstrap navbar, but the tabs are generated at runtime. It's this way because they link to show/:id and a user can delete the record associated with that tab at any time. I created the links like this:
<% #groups.each do |group| %>
<li id=<%= group.id %>><%= link_to t("navbar." + group.name.singularize.downcase), :controller => 'groups', :action => 'show', :id => group.id %></li>
<% end %>
This works fine until I use Devise and attempt to get to /admins/sign_in. The navbar code is still exactly the same, but I get an UrlGenerationError:
No route matches {:action=>"show", :controller=>"devise/groups", :id=>4, :locale=>nil}
My guess is the error stems from the controller being "devise/groups" as that's the only difference I spot. Is there a way I can tell it to not prepend "devise"? Or do I have to write new routes for all these bits? If I have to add new routes, how can I use resources in routes?
I suspect Devise will also break other links on other pages that I had to code this way.
routes:
Rails.application.routes.draw do
devise_for :admins
get 'search/index'
get 'tags/:tag', to: "search#index", as: :tag
scope "(:locale)", :locale => /#{I18n.available_locales.join("|")}/ do
get 'home/index'
root :to => "home#index"
resources :brands
resources :faqs
resources :categories
resources :subgroups
resources :groups
end
UPDATE: I tried changing the link to the following
<% #groups.each do |group| %>
<li id=<%= group.id %>><%= link_to(t("navbar." + group.name.singularize.downcase), url_for(:controller => 'groups', :action => 'show', :id => group.id)) %></li>
<% end %>
But it still comes up with "devise/groups" as the controller when I access the sign-in page. After I sign in, there's no problem.
I have a strange "fix" but it certainly does not feel correct in the slightest. I created new Controllers that derive from Devise::[name]Controllers, and did the following to whatever methods I needed
def new
super
end
Then edited routes.rb
devise_for :admins, :controllers => {:[name] => "[name]"}
with a new :[name] => "[name]" pair for each Controller I had to make.
determined which ones I needed by looking at rake routes. Everything's working, but I'm sure there's a cleaner fix than this out there.
p.s. you may need to run rails g devise:views

Rails 4 shallow nesting UrlGenerationError, missing required keys

I'm trying shallow nested resources for the first time and having a little trouble with one my index routes.
routes.rb
resources :sites, shallow: true do
resources :visits
end
The error I get is in my visits#show page's back button:
<%= link_to 'Back', site_visits_path(#site) %>
No route matches {:action=>"index", :controller=>"visits", :site_id=>nil} missing required keys: [:site_id]
In the index action of my VisitsController I set#site as follows:
#site = Site.find(params[:site_id])
However it's saying my :site_id is nil and I'm not sure how to set this correctly.
You can set that like:
<%= link_to 'Back', site_visits_path(:site_id => #site.id) %>

Calling a custom action within a nested resource (Rails 3)

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.

Rails 3 Routing: non-CRUD controller

I need a bit of help with converting routing from Rails 2 to Rails 3.
In app/views/layouts/application.html.erb, I have:
<%= link_to "Reports", reports_path %><br>
There is a ReportsController, and in app/views/reports/index.html.erb, I have this:
<%= link_to "Clients With Animals", :action => "getAnimals", :controller => "clients" %>
Then, in config/routes.rb, I have this (Rails 3)
match '/reports' => "reports#index"
match '/clients/getAnimals', to: "clients#getAnimals"
I get this error when I click on the "getAnimals" link on the reports page:
ActiveRecord::RecordNotFound in ClientsController#show
Couldn't find Client with id=getAnimals
I don't want "getAnimals" to be the ID - I want it to be the action, instead.
How do I do that?
Assuming you also have a resources :clients entry, you want to make sure match '/clients/getAnimals', to: "clients#getAnimals" is above it (Rails will match whatever it hits first).
However, the better way may be to put it in the resource:
resources :clients do
get 'getAnimals', :on => :collection
end

How to write match in route.rb

In my AdminController, I have methods named as edit, update and update_admin. And in route.rb
resources :session, :only => [update]
match '/:controller(/:action(/:id))'
end
When I navigate the url '/users/edit/1' matches. From this page i want to call the action method in update_admin in AdminController. How to do this?
My edit.erb has
<%= render :partial => '/submit', :locals =
> {:button_html => f.submit('Update'), :validate_present => true}
%>
at first, to check your routes go to console and do
rake routes | grep session
there you will get list all routes of your rails application (matched to the grep)
at second i dont get your routes.rb
would you do
resources :session, :only => [update] do
match '/:controller(/:action(/:id))'
end
or
resources :session, :only => [update]
match '/:controller(/:action(/:id))'
end
these are 2 different things. i think you want the last one. but here we go, there is another problem
resources :session, :only=>[update]
this throws an error.(undefined local variable or method `update' for #)
if you want to specify actions, you need to do it as a key
resources :session, :only=>[:update]
but you also want the edit message, (edit is the form, update the action to save the changes) so you have to do
resources :users, :only=>[:edit, :update]
now check your rake routes and see voila!
edit_session GET /session/:id/edit(.:format) {:action=>"edit", :controller=>"session"}
session PUT /session/:id(.:format) {:action=>"update", :controller=>"session"}
//edit
if you want to do this in your admin_controller you should have a namespace
#i take example for a user
namespace :admin do
resources :user :only => [:edit, :update]
end
if you want now to link to it from a view the route is named
edit_admin_user_path
and in a form you need to bring the namespace also in the form_for like:
=form_for [:admin, #user] do |f|

Resources