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) %>
Related
I've created a controller Pages and some actions for simple pages (contact us, for instance), then I went to routes.rb and created a route to allow users to go directly to /contactus, instead of /pages/contactus.
How can I point link_to to the action, but still getting the right route url?
get :contact_us, to: 'pages#contact_us'
or
get :contact_us, controller: :pages, action: :contact_us
this will generate path contact_us_path or url contact_us_url
HEARE MORE ABOUT ROUTES IN RAILS
#config/routes.rb
resources :pages, path: "", only: [] do #-> has to be above everything in routes file
collection do
get :contact_us #-> url.com/contact_us
get :about #-> url.com/about
end
end
root ...
You'd link to it as follows:
<%= link_to "Contact", pages_contact_us_path %>
You can do this:
get '/contactus', to: 'pages#contactus'
Your link can be:
<%= link_to "Contact Us", contactus_path %>
For more information, see: http://guides.rubyonrails.org/routing.html#connecting-urls-to-code
This is the syntax for a simple route using the contactus action in the pages controller:
get '/contactus' => 'pages#contactus'
or if you want a simpler name for your path:
get '/contactus' => 'pages#contactus', as: :contact
I have a custom rails route defined as such:
resources :scores, path: "seasons/:season_id/scores/:student_id"
This makes sense for my application and would keep the urls standardized. This works for the show page and I am able to grab :season_id and :student_id properly.
However, when I try to route to any of the other pages I get errors. I wanted the new and edit page to be these routes:
New
resources :scores, path: "seasons/:season_id/scores/:student_id/new"
Edit
resources :scores, path: "seasons/:season_id/scores/:student_id/:id/edit"
So they still follow normal conventions, and that's what happens when I run rake routes, but hitting any route throws:
ActionController::UrlGenerationError
No route matches {:action=>"show", :controller=>"scores", :format=>nil, :id=>nil, :season_id=>#<Score id: ... >, :student_id=>nil} missing required keys: [:id, :student_id]
Which is weird on two accounts. The season id is being linked to the score object, and it says there are missing keys. All keys are present in the params hash, and this is how I'm building my links:
= link_to "Edit", { controller: :scores, action: :edit, id: score.id, student_id: params[:student_id], season_id: params[:season_id]} , class: "btn btn-success btn-xs"
It's better not to use resources plus path when you need to nest a resource. It's more easy to read and understand, less error prone and it's the Rails convention.
You can write your routes like this:
resources :seasons do
resources :students do
resources :scores
end
end
And then use the named path method in your link like this:
link_to "Edit", edit_score_student_season_path(score, params[:student_id], params[:season_id]), class: "btn btn-success btn-xs"
I have created a nested routes like this
resources :subjects do
resources :subject_edits do
member do
post :vote
end
end
end
when I run rake routes, I found it exited
vote_subject_subject_edit POST /subjects/:subject_id/subject_edits/:id/vote(.:format) subject_edits#vote
but when I use it in my .erb file
<%= button_to 'I Agree', :action => vote_subject_subject_edit_path(#subject, #edit) %>
I got an error,
No route matches {:action=>"/subjects/25/subject_edits/1/vote",
:subject_id=>"25", :id=>"1", :controller=>"subject_edits"}
what is wrong here?
This helper sets url explicitly, so you need:
<%= button_to 'I Agree', vote_subject_subject_edit_path(#subject, #edit) %>
without passing :action option.
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.
This is my route:
scope ":username" do
resources :feedbacks
end
I am on my home/index.html.erb view and I am trying to do this:
<%= render "feedbacks/form" %>
But this gives me this error:
ActionView::Template::Error (No route matches {:controller=>"feedbacks", :format=>nil}):
1: <%= form_for(#feedback) do |f| %>
2: <% if #feedback.errors.any? %>
3: <div id="error_explanation">
4: <h2><%= pluralize(#feedback.errors.count, "error") %> prohibited this feedback from being saved:</h2>
app/views/feedbacks/_form.html.erb:1:in `_app_views_feedbacks__form_html_erb__3181571289116259961_2487495480'
app/views/home/index.html.erb:18:in `_app_views_home_index_html_erb___397233383548615486_2487321620'
This is my rake routes for feedbacks:
feedbacks GET /:username/feedbacks(.:format) {:action=>"index", :controller=>"feedbacks"}
POST /:username/feedbacks(.:format) {:action=>"create", :controller=>"feedbacks"}
new_feedback GET /:username/feedbacks/new(.:format) {:action=>"new", :controller=>"feedbacks"}
edit_feedback GET /:username/feedbacks/:id/edit(.:format) {:action=>"edit", :controller=>"feedbacks"}
feedback GET /:username/feedbacks/:id(.:format) {:action=>"show", :controller=>"feedbacks"}
PUT /:username/feedbacks/:id(.:format) {:action=>"update", :controller=>"feedbacks"}
DELETE /:username/feedbacks/:id(.:format) {:action=>"destroy", :controller=>"feedbacks"}
Edit 1
When I pass in the local instance variable #feedback like this: <%= render "feedbacks/form", :local => #feedback %> which is pulling from my home controller, where it is declared like this:
class HomeController < ApplicationController
def index
#users = User.all
#feedback = Feedback.new
end
end
I still get this error:
Routing Error
No route matches {:controller=>"feedbacks", :format=>nil}
Edit 2
I also have a users resource specified in my routes file, that looks like this:
resources :users
scope ":username" do
resources :feedbacks
end
Seems like form_for can't find the correct route, this line suggests you don't have an instance variable #feedback set when trying to render that partial:
(No route matches {:controller=>"feedbacks", :format=>nil})
Notice there is no :id parameter in that hash (which is likely being passed to the router to generate the correct URL to submit the form to).
Do you define a #feedback somewhere in the controller action (preferable) or views you're using? If you think you are, try the following above line 1 of your partial:
logger.info "feedback object: #{#feedback.inspect}"
Edit:
First of all, locals should be passed not as :local => #feedback but as:
:locals => {:variable_name_in_partial => value_for_variable_name}
Second of all, you are trying to access #feedback which is an instance variable accessible to views even if it's not passed explicitly (as long as it's set). So as long as you set it in the HomeController#index method you don't need to pass it to any views locally.
Also, you are not using the correct syntax for rendering partials (wish I had noticed earlier!).
Change the following:
<%= render "feedbacks/form" %>
To this:
<%= render :partial => "feedbacks/form" %>
Aren't you forgetting to pass in :username? Your route says scope :username
If I add a route like yours, open up the Rails console, include Rails.application.routes.url_helpers and run feedbacks_path, I get a routing error, but feedbacks_path :username => 'bob' works fine.
> feedbacks_path(:username => 'bob')
=> "/bob/feedbacks"
Are you sure you want scope? What about a nested resource as per:
resources :users do
resources :feedbacks
end
Also, I've had trouble when using controllers with plural names. You might try renaming FeedbacksController to FeedbackController.