link_to update for a nested resource not working - put

The link in _applicant.html.erb looks like this in the browser: http://localhost:3000/needs/3/applicants.1
and when clicked on this shows up in the browser:
Routing Error
No route matches [PUT] "/needs/3/applicants.1"
I want it to update the acceptance column for this particular applicant row. Basically I want it to send data to the update method of the applicants controller. How can I modify the code to do this?
_applicant.html.erb
<%= link_to 'Accept Applicant', need_applicants_path(applicant.need_id, applicant.id), :method => :put, :action => "update", :applicant => {:acceptance => true} %>
got this from running rake routes:
PUT /needs/:need_id/applicants/:id(.:format) applicants#update
routes.rb:
resources :needs, except: [:new] do
resources :applicants
end
applicants_controller.rb
class ApplicantsController < ApplicationController
def update
#need = Need.find(params[:need_id])
#applicant = #need.applicants.find(params[:id])
if #applicant.update_attributes(params[:applicant])
flash[:success] = 'Your applicant has been accepted/rejected!'
redirect_to #need
else
#need = Need.find(params[:need_id])
render 'needs/show'
end
end
end

I think there are two possible fixes here:
First,
http://localhost:3000/needs/3/applicants.1
should probably read
http://localhost:3000/needs/3/applicants/1
The error is in this line:
<%= link_to 'Accept Applicant', need_applicants_path(applicant.need_id, applicant.id), :method => :put, :action => "update", :applicant => {:acceptance => true} %>
where...
need_applicants_path(applicant.need_id, applicant.id)
You can try passing in two instance objects like so:
need_applicants_path(Need.find(applicant.need_id), applicant)
Second, another possible solution is to explicitly set the PUT path in your routes.
In your config/routes.rb add the line
put 'need/:need_id/applicant/:id/update
then run
rake routes
and see what the PUT path is

Related

Rails nested resources and path

I've got a nested resource:
def workspace
has_many :instances
end
def instance
belongs_to :workspace
end
and some nested routes
resources :workspaces do
resources :instances do
end
end
resources :instances
That way, I can visit the following path and get the same result:
workspaces/1/instances
/instances
On my 'view/instances/index.html.erb' I have a custom pagination link, where I reload the page with additional params.
If I am in workspaces/1/instances, the link should be:
= link_to "← Previous", workspace_instances_path(:param => "data")
But, if I am in /instances:
= link_to "← Previous", instances_path(:param => "data")
How can I have a single link_to, that works for both routes? Preferably without listing all possible cases, just a single line
link_to lets you specify the controller and action in place of the named route. Assuming that the same controller action will handle the request you could specify the controller and action
link_to "previous", :controller => "instances", :action => "my_action", :data => "data"

Routing and form in Rails

I have a controller for a resource, BuddiesController. My routes config file up until now has been
resources :buddies
match ':controller(/:action(/:id))', :via => [:get, :post]
I didn't realize what the ' resources :buddies ' line was doing until I read up on routing in Rails just now, because the behavior has been identical with what I expected until now. The problem was that I wanted to add a non-CRUD action to the controller: 'search'. Every time I used link_to(:action => 'search'), I would get an exception saying that action 'show' could not be found despite the url being ' localhost:3000/buddies/search ' as expected. I have several questions arising from this:
Firstly, the form I used in 'new' stopped working:
%= form_for(#buddy, {:action => :create, :method => :post, :html => {:role => "form"}}) do |f| %>
because buddies_path couldn't be found. How could I manually add a buddies_path to my routes?
Secondly, I revised the form to use:
<%= form_for(#buddy, :url => {:action => :create, :id => #buddy.id}, :html => {:role => "form", :id => #buddy.id}) do |f| %>
but this has caused the form to give me password and email confirmation not matching errors even if they match. What's going on here?
Lastly, what is the best way to add a search action to my resource?
#routes.rb
resources :buddies
collection do
get :search
end
end
now when you run rake routes | grep 'buddies' you will get output something like this :
now you need to define this search action in your buddies controller .
#buddies_controller.rb
Class BuddiesController < ApplicationController
def search
end
end
Have your search form in app/views/buddies/search.html.erb
Now in order to open your search form / to hit your search action you need to use
<%= link_to 'Search XYZ', search_buddies_path %>
against buddies#search you can see search_buddies
In routes.rb:
resources :buddies do
collection do
post :search
end
end
This might make your routing works.

Rails path gives me no route matches, but I don't understand why

so I have a very simple I think layout. My config routes is:
resources :webcomics
match '/webcomics/first' => 'webcomics#first', :as => :first
match '/webcomics/random' => 'webcomics#random', :as => :random
match '/webcomics/latest' => 'webcomics#latest', :as => :latest
Controller:
def show
#webcomic = Webcomic.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #webcomic }
end
end
def first
#webcomic = Webcomic.order("created_at ASC").first
respond_to do |format|
format.html { render 'show'}
format.json { render json: #webcomic }
end
end
navigation bar:
<%= link_to first_webcomics_path, :rel => "tooltip", :title => "first comic" do %>
formatting in here
<% end %>
when I click on this link, it sends me to the right path /webcomics/first, BUT it gives me the error
Routing Error
No route matches {:action=>"edit", :controller=>"webcomics"}
I am breaking my head how is it going to 'EDIT', and no matter this message is totally wrong, I do have edit, but why does it try to go to action edit.
def edit
#webcomic = Webcomic.find(params[:id])
end
Results of rake routes:
first_webcomics GET /webcomics/first(.:format) webcomics#first
latest_webcomics GET /webcomics/latest(.:format) webcomics#latest
random_webcomics GET /webcomics/random(.:format) webcomics#random
webcomics GET /webcomics(.:format) webcomics#index
POST /webcomics(.:format) webcomics#create
new_webcomic GET /webcomics/new(.:format) webcomics#new
edit_webcomic GET /webcomics/:id/edit(.:format) webcomics#edit
webcomic GET /webcomics/:id(.:format) webcomics#show
PUT /webcomics/:id(.:format) webcomics#update
DELETE /webcomics/:id(.:format) webcomics#destroy
root / webcomics#index
Routing is in order; put the matches above the resources.
That said, I'd consider adding those routes as RESTful actions instead:
resources :webcomics
collection do
get 'first'
get 'random'
get 'latest'
end
end
IMO this is a bit cleaner, and happens to fit reasonably well.
The issue is because of your edit link in the show template. Edit links require an object to
edit:
<%= link_to "edit", edit_webcomic_path(#webcomic) %>
Put those three match rules above the resources line like that:
match '/webcomics/first' => 'webcomics#first', :as => :first
match '/webcomics/random' => 'webcomics#random', :as => :random
match '/webcomics/latest' => 'webcomics#latest', :as => :latest
resources :webcomics
The reason is explained in Ruby Guides: Routing:
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.

url action is not working in my rails

I made a salaries controller inside the folder employee.
In my routes:
namespace :employee do
resources :salaries
end
Now in my salaries controller I added a new method action_list:
class Employee::SalariesController < ApplicationController
def action_list
end
end
From view inside index I want to call action_list like:
<%= form_for :form, :url => {:action => 'action_list'}, :method => :post,
:html => {:id => 'form1', :onsubmit => "return checkCheckBoxes();"} do |f| %>
When I submit the form I get the following error:
No route matches [POST] "/employee/salaries/action_list"
What could be the problem? It works fine for other controllers without using a namespace.
What am I doing wrong?
have you added action_list onto your routes
namespace :employee do
resources :salaries do
post :action_list, :on => :collection
end
end
Add a route for the action_list action:
namespace :employee do
resources :salaries do
post 'action_list'
end
end
Read more about adding restful routes here.

Rails not finding controller action

So, I have the following link-to:
<%= link_to(outing_add_guests_path, :class => 'modal') do %>
<div id="notImportant"></div>
<% end %>
When I click on it, Rails tells me that
No route matches {:controller=>"outings", :action=>"add_guests"}
However, here's my routes file:
resources :outings do
get "/add_guests" => "outings#add_guests"
post "/add_guests" => "outings#add_guests"
delete "/remove_guests" => "outings#remove_guests"
end
and the corresponding action from my Outings Controller:
def add_guests
#outing_guest = OutingGuest.new(:outing_id => params[:outing_id])
#outing_guest.user_id = params[:user_id]
if #outing_guest.save
flash[:notice] = "Guest added successfully"
redirect_to({ :action => 'outing', :id => params[:outing_id] })
else
flash[:notice] = "Guest could not be added"
redirect_to({ :action => 'outing', :id => params[:outing_id] })
end
end
Is there any reason Rails would be unable to detect my controller or its actions?
EDIT: Here's part of the results from rake routes
outing_add_guests GET /outings/:outing_id/add_guests(.:format) outings#add_guests
POST /outings/:outing_id/add_guests(.:format) outings#add_guests
I notice your link_to is not consistent with the other routes
outing_add_guests_path
outings_add_guests_path
Did you do rake routes to verify that outing_add_guests_path exists?
EDIT:
Your rake routes shows you need an outing_id so your routes aren't setup right (at least not for the POST). I'd fix them the way #RyanBigg is suggesting.
You should be defining these routes using the collection method:
resources :outings do
collection do
get :add_guests
post :add_guests
delete :remove_guests
end
end
What this will do is define new routes for the specified actions, as well as automatically defining the routing helpers for those routes. For more information please read the Routing Guide.

Resources