Params passed into URL Ruby on Rails - ruby-on-rails

I'm having some issue with my form_tag search functionality is not redirecting me properly to a place where I can see the results of my search.
It was working fine yesterday, Once the submit button of the search is clicked, a get request to the pets controller search method is fired and then I was redirected to the results.html.erb page where the results are displayed.
The problem is that now when I submit the search, it's just refreshing the page (index.html.erb) and my params are passed to the URL but none of the "pets" i searched for are displayed.
http://localhost:3000/?utf8=%E2%9C%93&authenticity_token=iDXugIhTyjknCMpPh2P5x7voNMSQ3Y7Aa1HIZPA7xqZ9Oj4CAuVc5eJPqfE1CLwxXAsCebgPuNWqpOk381TlvQ%3D%3D&pets%5Bzip_code%5D=10019&pets%5Bspecies%5D=Cat&pets%5Bbreed%5D=&pets%5Bage%5D=&pets%5Bsex%5D=&pets%5Bsize%5D=&commit=Find+Pets%21
Before it was just redirecting me the results page localhost:3000/results
Here is my pets controller
class PetsController < ApplicationController
def index #index page will render search form
#pet = Pet.new
#send form data in params to create
end
def search
#pets = Pet.where(clean_params)
render :results
end
private
def thinned_params
params["pets"].delete_if {|k, v| v.empty?}
end
def clean_params
thinned_params.permit(:species, :zip_code, :sex, :size, :breed, :age)
end
end
My form_tag in welcome#index:
<form class="form-horizontal">
<%= form_tag :controller => 'pets', :action => 'search', :method => 'get' do %>
<%= label_tag('pets[zip_code]', "Zipcode") %>
<%= text_field_tag('pets[zip_code]') %>
<%= label_tag('pets[species]', "Type") %>
<%= select_tag('pets[species]', options_for_select([["Dog","Dog"],["Cat","Cat"],["Rabbit", "Rabbit"], ["Small & Furry","Smallfurry"],["Horse", "Horse"],["Pig", "Pig"],["Reptile", "Reptile"],["Bird", "Bird"],["Barnyard", "Barnyard"]])) %>
<%= label_tag('pets[breed]', "Breed") %>
<%= text_field_tag('pets[breed]', nil, class: 'typeahead') %>
<%= label_tag('pets[age]', "Age") %>
<%= select_tag('pets[age]', options_for_select([["None",""],["Baby","Baby"],["Young","Young"],["Adult", "Adult"], ["Senior","Senior"]])) %>
<%= label_tag('pets[sex]', "Gender") %>
<%= select_tag('pets[sex]', options_for_select([["None",""],["Male","M"],["Female","F"]])) %>
<%= label_tag('pets[size]', "Size") %>
<%= select_tag('pets[size]', options_for_select([["None",""],["Small","S"],["Medium","M"], ["Large", "L"], ["Xtra Large", "XL"]])) %>
<%= submit_tag "Find Pets!" %>
<%end%>
</form>
And finally...my routes.rb
Rails.application.routes.draw do
devise_for :users
resources :users
# resources :pets
root 'welcome#index'
get '/pets' => 'pets#index'
post '/pets/search' => 'pets#search'
resources :favorite_pets
get '/my_pets' => 'users#my_pets'
end
So my question is why is my params passed to the URL when it should just hit the search method in the pets controller and redirect me to the results page displaying the info?
Second question, obviously, what can I do to fix this problem?
UPDATE
here is the output of my console when the "search" button is clicked.
Started GET "/?utf8=%E2%9C%93&authenticity_token=NgVe%2Fe5i6sn8ijRmgcvOezp62KlymrNRWPJfFNOVJ54ChWpZf8JYTm%2Fk%2FeHdDsvcgzdBYe%2BjUX5jiz2JeALEpQ%3D%3D&pets%5Bzip_code%5D=10019&pets%5Bspecies%5D=Cat&pets%5Bbreed%5D=&pets%5Bage%5D=&pets%5Bsex%5D=&pets%5Bsize%5D=&commit=Find+Pets%21" for ::1 at 2015-03-15 15:54:34 -0400
Processing by WelcomeController#index as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"NgVe/e5i6sn8ijRmgcvOezp62KlymrNRWPJfFNOVJ54ChWpZf8JYTm/k/eHdDsvcgzdBYe+jUX5jiz2JeALEpQ==", "pets"=>{"zip_code"=>"10019", "species"=>"Cat", "breed"=>"", "age"=>"", "sex"=>"", "size"=>""}, "commit"=>"Find Pets!"}
Pet Load (0.7ms) SELECT "pets".* FROM "pets"
CACHE (0.0ms) SELECT "pets".* FROM "pets"
CACHE (0.0ms) SELECT "pets".* FROM "pets"
CACHE (0.0ms) SELECT "pets".* FROM "pets"
Breed Load (0.2ms) SELECT "breeds".* FROM "breeds" INNER JOIN "pet_breeds" ON "breeds"."id" = "pet_breeds"."breed_id" WHERE "pet_breeds"."pet_id" = ? [["pet_id", 71]]
Shelter Load (0.1ms) SELECT "shelters".* FROM "shelters" WHERE "shelters"."id" = ? LIMIT 1 [["id", 26]]
Breed Load (0.3ms) SELECT "breeds".* FROM "breeds" INNER JOIN "pet_breeds" ON "breeds"."id" = "pet_breeds"."breed_id" WHERE "pet_breeds"."pet_id" = ? [["pet_id", 73]]
CACHE (0.0ms) SELECT "shelters".* FROM "shelters" WHERE "shelters"."id" = ? LIMIT 1 [["id", "26"]]
Breed Load (0.1ms) SELECT "breeds".* FROM "breeds" INNER JOIN "pet_breeds" ON "breeds"."id" = "pet_breeds"."breed_id" WHERE "pet_breeds"."pet_id" = ? [["pet_id", 41]]
Shelter Load (0.1ms) SELECT "shelters".* FROM "shelters" WHERE "shelters"."id" = ? LIMIT 1 [["id", 16]]
Breed Load (0.1ms) SELECT "breeds".* FROM "breeds" INNER JOIN "pet_breeds" ON "breeds"."id" = "pet_breeds"."breed_id" WHERE "pet_breeds"."pet_id" = ? [["pet_id", 9]]
Shelter Load (0.1ms) SELECT "shelters".* FROM "shelters" WHERE "shelters"."id" = ? LIMIT 1 [["id", 5]]
Rendered welcome/index.html.erb within layouts/application (20.9ms)
Completed 200 OK in 127ms (Views: 125.2ms | ActiveRecord: 1.6ms)
Rake Routes
https://slack-files.com/files-pub/T02MD9XTF-F041PKBE2-532b801cb1/-.txt

According to your routes file, the search action only accepts POST (not GET):
post '/pets/search' => 'pets#search'
That seems appropriate, so just change your form action to use the POST method:
form_tag :controller => 'pets', :action => 'search', :method => :post

Your route is POST, but that makes no sense, are you trying to update or replace pets? No, you getting a list of pets. You are already calling a GET request in your form, so you can leave that, and change
post '/pets/search' => 'pets#search' to get '/pets/search' => 'pets#search'
More information on get and post.

Related

How to pass data from view that came from an external API to a controller?

So I want to pass a data from a view that was rendered from an external api to a controller to be able to save the ID to a model/database table.
This is my view:
<h1>Heroes</h1>
<% #response.each do |hero| %>
<div class = "hero_wrap">
<div class = "img">
<img src="https://api.opendota.com<%= hero["img"]%>", id ="hero_img"/>
</div>
<div class = "fave_container">
<%= link_to(image_tag('fave.png', class: "fave_img"), new_hero_path) %>
<%= hero["id"]%>
</div>
<div class = "hero_name">
<%= hero["localized_name"] %>
</div>
</div>
<% end %>
My controller:
# heroes_controller
class HeroesController < ApplicationController
def index
#response = HTTParty.get("https://api.opendota.com/api/heroStats")
end
def create
#hero= Hero.new(params[:id])
#hero.save
redirect_to #hero
end
end
Routes:
Rails.application.routes.draw do
get '/signup', to: 'users#new'
get 'pages/home'
resources :pro_players
devise_for :users
resources :heroes
resources :users
root 'pages#home'
end
My hero model doesn't contain anything yet, I just want to pick the hero id and save it to my database.
this is my web app
server log upon clicking the star icon with link:
Started GET "/heros?custom_hero_id=1&method=post" for 127.0.0.1 at
2018-10-15 09:20:53 +0800
Processing by HerosController#index as HTML
Parameters: {"custom_hero_id"=>"1", "method"=>"post"}
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
↳/home/don/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-
5.2.1/lib/active_record/log_subscriber.rb:98
Rendering heros/index.html.erb within layouts/application
Rendered heros/index.html.erb within layouts/application (42.2ms)
Rendered layouts/_header.html.erb (1.1ms)
Rendered layouts/_footer.html.erb (0.4ms)
Completed 200 OK in 770ms (Views: 83.3ms | ActiveRecord: 0.7ms)
Updated log:
Started POST "/heros?custom_hero_id=21" for 127.0.0.1 at 2018-10-15 10:13:17 +0800
Processing by HerosController#create as HTML
Parameters: {"authenticity_token"=>"PHDEXdDmPhPX+VdloU2y6yONY5HN5wI2lIfOaSbSKj9+RvTO5Ua3QPuTcreLZtGNDFPaSOXhDVyve6J69+1CQQ==", "custom_hero_id"=>"21"}
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
↳/home/don/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
(0.2ms) BEGIN
↳ app/controllers/heros_controller.rb:9
Hero Create (0.4ms) INSERT INTO "heros" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id" [["created_at", "2018-10-15 02:13:17.032248"], ["updated_at", "2018-10-15 02:13:17.032248"]]
↳ app/controllers/heros_controller.rb:9
(42.3ms) COMMIT
↳ app/controllers/heros_controller.rb:9
Redirected to http://localhost:3000/heros/10
Completed 302 Found in 59ms (ActiveRecord: 46.9ms)
Started GET "/heros/10" for 127.0.0.1 at 2018-10-15 10:13:17 +0800
AbstractController::ActionNotFound (The action 'show' could not be found for HerosController):
The :id attribute is by default a auto-increment attribute of datatype integer which sets its value under the hood whenever a new instance of the model is created. There are several ways to override the its behavior or setting its value explicitly, but considering that you are fairly new to the technology I don't recommend those for you. Instead I recommend a simpler solution of using another attribute to store hero["id"]
Steps:
1) Generate a migration to create a new column(say custom_hero_id) in the heroes table
rails g migration add_custom_hero_id_to_heroes custom_hero_id:integer
and do rake db:migrate
2) Change
<%= link_to(image_tag('fave.png', class: "fave_img"), new_hero_path) %>
to
<%= link_to(image_tag('fave.png', class: "fave_img"), heroes_path(custom_hero_id: hero["id"]), method: :post) %>
3) Finally change your create action to below
def create
#hero= Hero.create(custom_hero_id: params[:custom_hero_id])
redirect_to #hero
end
Update:
Due to unknown reason, custom_hero_id isn't saving to the DB. Probably due to forbidden attributes error. Try changing it to
def create
#hero = Hero.new(hero_params)
if #hero.save
redirect_to #hero
end
end
private
def hero_params
params.permit(:custom_hero_id)
end
Do you want to store the hero id or it's name ?
I would advise to create a method in your heroe model. Something like
// heroe.rb
def save_api_heroes_to_db(response)
response.each do |hero|
unless hero[:localized_name].exists?
hero.create(id: hero[:id], name: hero[:localized_name], image: hero[:img])
end
end
end
This method will save the heroe id, name and image in your database (unless it already exists).
You just have to call it in your index method, in your heroe controller.
Hope that helps.

Rails 5.1 strong parameters deprecated?

I'm working on using form_with in Rails 5.1.3 & Ruby 2.3.0
The best documentation I've found is here
Rails Github Repo on line 533, but it's still unclear to me.
# The parameters in the forms are accessible in controllers according to
# their name nesting. So inputs named +title+ and <tt>post[title]</tt> are
# accessible as <tt>params[:title]</tt> and <tt>params[:post][:title]</tt>
# respectively.
Code:
# friendships_controller.rb
...
private
def friendship_params
params.require(:friendship).permit(:user_id, :id)
end
# Works
def destroy
Friendship.remove_friend(current_user.id, params[:id].to_i)
end
# Doesn't work
def destroy
Friendship.remove_friend(friendship_params[:user_id].to_i, friendship_params[:id].to_i)
end
# form_with
<%= form_with model: Friendship,
url: user_friendship_path(
user_id: current_user.id
id: other_user.id,
), method: :delete do |f| %>
<button class='button'></button>
<% end %>
I know the naming is a little confusing, I still haven't figured out how to get form_with to map correctly to the route I need.
friendships#destroy located at path
/users/:user_id/friendships/:id(.:format)
resources :users do
resources :friendships
end
Error Message
Started DELETE "/users/1/friendships/8" for 127.0.0.1 at 2018-01-02 03:21:40 +0700
Processing by FriendshipsController#destroy as JS
Parameters: {"utf8"=>"✓", "authenticity_token"=>"fWnYwpNDItctgg3q/TYIXy5VRO55nwQRINCCykMsDPAFBfwJKjMZ1dneNbg 5yFNHaQP+lXR4ViTje6mK+dCmVg==", "user_id"=>"1", "id"=>"8"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
(0.2ms) BEGIN
(0.1ms) COMMIT
Friendship Load (1.0ms) SELECT "friendships".* FROM "friendships" WHERE "friendships"."friend_id" = $1 AND "friendships"."user_id" = $2 ORDER BY "friendships"."id" ASC LIMIT $3 [["friend_id", 1], ["user_id", 8], ["LIMIT", 1]]
SQL (1.2ms) DELETE FROM "friendships" WHERE "friendships"."id" = $1 [["id", 499]]
Friendship Load (0.5ms) SELECT "friendships".* FROM "friendships" WHERE "friendships"."friend_id" = $1 AND "friendships"."user_id" = $2 ORDER BY "friendships"."id" ASC LIMIT $3 [["friend_id", 8], ["user_id", 1], ["LIMIT", 1]]
SQL (0.9ms) DELETE FROM "friendships" WHERE "friendships"."id" = $1 [["id", 498]]
Completed 400 Bad Request in 13ms (ActiveRecord: 4.2ms)
ActionController::ParameterMissing (param is missing or the value is empty: friendship):
app/controllers/friendships_controller.rb:40:in `friendship_params'
app/controllers/friendships_controller.rb:22:in `destroy'
Maybe I shouldn't say it doesn't work, the behavior is how I expect with or without the friendship_params. However, the server logs returning a 400 Bad Request is a red flag to me.
Thanks for any suggestions in advance~!
The route is a nested resource, so you should provide two arguments to the path. you also need to provide the scope to give it the "friendship" key in the params.
<%= form_with scope: :friendship, url: user_friendship_path(current_user, other_user), method: :delete do |f| %>
<button class='button'></button>
<% end %>
This code is little bit confusing, I suggesting the way for simple like change your route like below
resources :users do
resources :friendships
end
Change to
resources :users
resources :friendships
and on the view
<%= link_to "Remove Friend", friendship_path(friend_id), method: :delete, data: {confirm: "Are you sure"}, class: "btn btn-xs btn-danger" %>
and finally the controller
def destroy
#friendship = current_user.friendships.where(friend_id: params[:id]).first
#friendship.destroy
flash[:notice] = "Friend was removed"
redirect_to(my_friends_path)
end
Hope to help
The answer was that the arguments to the form_with don't pass the actually parameters to the key Friendship, we have to pass them manually within the body of the form.
<%= form_with model: Friendship, url:
user_friendship_path(
current_user, other_user
), method: :delete do |f| %>
<%= f.hidden_field :id, value: other_user.id %>
<button class='button'></button>
<% end %>

Adding a button on a specific page with backlinks

First post, so i'm a newbie in StackOverflow. I'm trying for several days to make appear a Return button on a page form but only on a specific one.
So, I was advised to use backlink to make it appears.
Here's my code from the form where I want the return button
<% if #backlink.present? %>
<div class="spacer30"></div>
<% if #backlink == 'infos' %>
path = membre_path(menu: 'infos')
<% end %>
<% end %>
<%= link_to "Retour", path, class: "btn-rounded btn-turquoise btn-small" %>
Here's my code controller
def edit
super do |user|
puts "TEST PARAMS BACKLINK #{params[:backlink]}"
#backlink = params[:backlink]
end
end
and my route's :
get 'change_password', to: 'users/registrations#edit'
put 'update' => 'users/registrations#update', :as => 'user_registration'
get 'edit_password', to: 'users/registrations#edit', :as => 'user_edit'
So i should have in my log my PUTS 'TEST PARAMS BACKLINK' but nothing appear, only :
Started GET "/change_password.1?backlink=infos" for ::1 at 2017-10-04 10:07:41 +0200
Processing by Users::RegistrationsController#edit as
Parameters: {"backlink"=>"infos"}
User Load (9.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
Rendering users/registrations/edit.html.erb within layouts/application
Rendered users/registrations/edit.html.erb within layouts/application (14.4ms)
Rendered shared/_navbar.html.erb (4.0ms)
Rendered shared/_flashes.html.erb (1.1ms)
Completed 200 OK in 231ms (Views: 217.0ms | ActiveRecord: 9.1ms)
Any ideas why it doesn't work?
Many thanks.
I just had to delete some lines, here's what i changed from my registration controller :
def edit
#backlink = params[:backlink]
super
end
This way, it appears exactly the way I wanted to.
Many thanks :)

Rails 5.0.1 Rendering to Excel not working

I have an app that helps a school to track students attendance to sports practices and games, I have all my index actions to render html, csv and xls formats and EVERYTHING GOES WELL. I have a special report that uses several model relations to complete, I am not required to render csv (I think this will be too complex to implement the to_csv method, I don't even have a clue where to put it, but this is not my problem), Now I created the equipos_controller#forma_rep method and a related view with a form to get the report's parameters, as you can see in the routes and controller code, it works fine when the report action renders the default HTML as you can see in the following log, parameters from the 'forma_rep.html.erb' form are in the params array..
Started POST "/equipos/reporte_asist" for 127.0.0.1 at 2017-01-05 18:37:51 -0600
Processing by EquiposController#reporte_asist as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"IP1O2bSgkGcSaUn5Sf9Tnp30yzxfP10+cA0h/1+XudoR7W8SoP6xveP3fwJpLFTvyRaBFdtqsqz5pCfYID5b5Q==", "entrenador"=>"1", "inicio"=>"2016-12-12", "final"=>"2016-12-20", "commit"=>"Crear Reporte"}
... most SQL ommited
Rendering equipos/reporte_asist.html.erb within layouts/application
Rendered equipos/reporte_asist.html.erb within layouts/application (69.4ms)
Rendered layouts/_shim.html.erb (0.5ms)
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
Rendered layouts/_header.html.erb (5.9ms)
Rendered layouts/_footer.html.erb (1.1ms)
Completed 200 OK in 210ms (Views: 165.2ms | ActiveRecord: 5.6ms)
But when I click the "Excel" link :
Started POST "/equipos/reporte_asist.xls" for 127.0.0.1 at 2017-01-05 18:37:56 -0600
Processing by EquiposController#reporte_asist as XLS
Parameters: {"authenticity_token"=>"oYVjNfxN5Qxt9FHC6PpeU0wQenD3p+otaxcGts1kZRuQlUL+6 BPE1pxqZznIKVkiGPIwWXPyBb/ivgCRss2HJA=="}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
Equipo Load (0.2ms) SELECT "equipos".* FROM "equipos" WHERE "equipos"."user_id" = ? [["user_id", 1]]
Completed 500 Internal Server Error in 11ms (ActiveRecord: 0.4ms)
NoMethodError (undefined method `<<' for nil:NilClass):
app/controllers/equipos_controller.rb:96:in `block in reporte_asist'
app/controllers/equipos_controller.rb:95:in `reporte_asist'
I can see that the parameters are not complete when I click the Excel link in the html file, how can I send them again? my routes work fine with the html version and the #index action renders fine in all formats, please help me.
Here is all code involved.
Routes:
resources :categorias
get '/equipos/forma_rep'
post '/equipos/reporte_asist', to: 'equipos#reporte_asist', as: 'reporte_asist'
resources :equipos
resources :players
app/controllers/equipos_controller.rb
def index
#equipos = Equipo.paginate(page: params[:page])
respond_to do |format|
format.html
format.csv { send_data #equipos.to_csv }
format.xls
end
end
# GET /equipos/forma_rep
def forma_rep
#equipo = Equipo.new
#entrenadores = User.all
end
# PUT /equipos/reporte_asist
def reporte_asist
if params[:entrenador]
#entrenador = User.find(params[:entrenador].to_i)
inicio = Time.parse(params[:inicio])
final = Time.parse(params[:final])
#equipos = #entrenador.equipos
#eventos = reporte(#entrenador.id, inicio, final)
else
#entrenador = current_user
#equipos = #entrenador.equipos
#equipos.each do |equi|
#eventos << equi.eventos
end
end
respond_to do |format|
format.html
format.xls
end
end
I have created the app/views/equipos/reporte_asist.xls.erb file with the XML directives as in..
<?xml version="1.0"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Worksheet ss:Name="Asistencias">
<Table>
<Row>
<Cell><Data ss:Type="String">Entrenador:</Data></Cell>
<Cell><Data ss:Type="String"><%= #entrenador.name %></Data> </Cell>
</Row>
....etc.
And this is the link I have in the app/views/equipos/reporte_asist.html.erb
<p>
Descargar:
<%= link_to "Excel", reporte_asist_path(format: "xls"), method: :post %>
</p>
Of course I have defined the Mime:Type.register in the config/initializers/mime_types.rb and requested the 'csv' library in my config/application.rb . I am using Rails 5.0.0.1 and Ruby 2.3.1 ...
This is the code that collects report parameter from user, it is inside the app/views/equipos/forma_rep.html.erb that posts to the reporte_asist.html.erb:
<h1>Reporte de Asistencias</h1>
<%= form_tag(reporte_asist_path) do %>
<%= label_tag(:entrenador, "Entrenador:") %>
<%= select_tag :entrenador, options_from_collection_for_select(#entrenadores, "id", "name"), prompt: "Seleccione el entrenador", class: 'form-control' %>
<%= label_tag(:inicio, "Fecha inicial de reporte:") %>
<%= date_field_tag :inicio, class: 'form-control' %>
<%= label_tag(:final, "Fecha final de reporte:") %>
<%= date_field_tag :final, class: 'form-control' %>
<%= submit_tag "Crear Reporte", class: "btn btn-default" %>
<% end %>
</div>
Initially this is the code that sends the report parameters, but once in the report view I cannot (and don't want to) re-render the form, that's why I put the link_to to the same controller but trying to render the excel
Add the parameters you want to POST to your reporte_asist_path helper, like this:
reporte_asist_path(format: 'xls', entrenador_id: #entrenador.id)
More information can be found here:
http://api.rubyonrails.org/classes/ActionDispatch/Routing/UrlFor.html#method-i-url_for
Also note that while using POST method for links is supported by Rails, it relies on JavaScript. If the user has JavaScript disabled, the request will fall back to GET method. So it's safer to use forms.

Rails Custom Route Redirecting to Show

I've created a custom route make_winner_pick but every time I click the link to follow the path the controller defaults to the show action. I can't understand what I'm doing wrong and it's driving me nuts
routes.rb
resources :league_members
get "league_members/make_winner_pick" => "league_members#make_winner_pick", :as => :make_winner_pick
Where the path is called
<%= link_to 'Join League', make_winner_pick_path(league: league.id), method: :get %>
The console
Started GET "/league_members/make_winner_pick?league=3" for 127.0.0.1 at 2015-08-29 01:33:56 +0100
Processing by LeagueMembersController#show as HTML
Parameters: {"league"=>"3", "id"=>"make_winner_pick"}
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = 2 ORDER BY "users"."id" ASC LIMIT 1
LeagueMember Load (0.5ms) SELECT "league_members".* FROM "league_members" WHERE "league_members"."id" = $1 ORDER BY "league_members"."id" ASC LIMIT 1 [["id", 0]]
Completed 404 Not Found in 5ms
ActiveRecord::RecordNotFound (Couldn't find LeagueMember with 'id'=make_winner_pick):
app/controllers/league_members_controller.rb:68:in `set_league_member'
Can anyone tell me why my custom route is not being fired and Rails is defaulting to the #show action? For some reason it appears to be looking for a league_member with an id of make_winner_pick
Thanks for looking.
Try nest your route within the resource:
resources :league_members do
collection do
get "make_winner_pick" => "league_members#make_winner_pick", :as => :make_winner_pick
end
end
Because rails recognized your route make_winner_pick as an id.
it should be:
<%= link_to 'Join League', league_members_make_winner_pick_path(league: league.id), method: :get %>

Resources