I wanted to hide params in rails url while searching.
so previously my link is like this,
http://localhost:3000/photos?utf8=%E2%9C%93&room_ids[]=534b6cc56d696e0f000d0000&commit=Refine+Search
i wanted to achieve like below link,
http://localhost:3000/photos
So i have changed the form_tag method to Post from Get.
<%= form_tag photos_path, :method => 'post' do %>
...
<% end %>
In route file mentioned as,
match '/photos/index', via: :post
After doing it giving error as,
ActionController::ParameterMissing in PhotosController#create
param not found: photo
How to achieve it!!!
If you want custom action to be performed on the params, better write a method in controller
#photos controller
def customize
#custom action on params
end
add the method 'customize' in the routes and specify the route in the form.
Also, if your form doesn't have any fields from Photo model, you can use ActiveModel::Model for projecting an object. Checkout http://blog.remarkablelabs.com/2012/12/activemodel-model-rails-4-countdown-to-2013 and http://prasadsurase.github.io/blog/2014/02/19/using-activemodel-model-for-devise-based-invitations/ describing about how to use ActiveModel::Model.
<%= form_tag photos_index_path, :method => 'post' do %>
or
match '/photos/index', via: :post, as: :photos
In termial, type rake routes
match '/photos/index' => photos_index /photos/index photos#index
match '/photos/index', via: :post, as: :photos => photos /photos/index photos#index
According to Rails Guide
Never use the legacy wild controller route. This route will make all actions in every controller accessible via GET requests.
# very bad
match ':controller(/:action(/:id(.:format)))'
Don't use match to define any routes. It's removed from Rails 4.
Related
I have a _form for new and edit for a #Giveaway object. Within this form I have a field for a random winner.
I want to populate this field by calling the method giveaways#random_winner with <%= button_to "Randomly Pick Winner!", {:action => 'choose_winner'}, :method => :get %>, but I am getting this error No route matches {:action=>"choose_winner", :controller=>"giveaways"} when loading /giveaways/new.
Here is my controller:
def choose_winner
random_winner = SubscriberUser.where(user_id: current_user.id).pluck(:subscriber_id).sample(1)
session[:random_winner] = random_winner
redirect_to :back
end
Here are the routes that I have tried. I'm not very good at non-scaffold routes yet:
resources :giveaways do
member do
get 'choose_winner' => 'giveaways#choose_winner'
#tried get :choose_winner, as: :choose_winner
#tried get 'new/choose_winner'
#tried get 'choose_winner'
#tried get 'choose_winner', to: 'giveaways#choose_winner', as: 'choose_winner'
end
end
Question -- Why is the page not loading when I have defined the controller and action in the route? Will I have to reload the page when I do run that route... is there a better way to get at this data?
Your routes.rb is close
resources :giveaways do
member do
get :choose_winner
end
end
And then I would use a Rails route helper so you don't have to worry about setting the action/controller yourself.
<%= button_to "Randomly Pick Winner", choose_winner_giveaway_path(#giveaway), method: :get %>
I've got a weird issue with one of my forms. The form only changes one variable of the object, called admin_comment. It ends up in the show method of the controller, in the terminal:
Processing by EnrolmentsController#show as
Here is the form_for
<%= form_for enrolment, :url => enrolments_admin_comment_path(enrolment), method: :get, remote: true do |f| %>
And here is the rake routes
enrolments_admin_comment GET /enrolments/admin_comment(.:format) enrolments#admin_comment
And the routes.rb part
get "enrolments/admin_comment"
resources :courses do
resources :enrolments
end
When I delete the method: :get part from the form_for, it ends up at the update method.
Everything else with the enrolments controller/model works fine. Does somebody know what's going on here? Thanks!
Update
After nearly getting insane I've got it working like this, but only with :get as method.
routes.rb
get "/enrolments/:id/admin_comment" => "enrolments#admin_comment", as: "enrolments_admin_comment"
form_for
<%= form_for enrolment, :url => enrolments_admin_comment_path(enrolment), method: :get, remote: true do |f| %>
If I change the method to :post, I get the following error:
ActionController::RoutingError (No route matches [POST] "/enrolments/28/admin_comment"):
Two questions came up:
1. What do I have to change to make it work with :post?
2. As far as I understand, if I just would just state the controller and the verb (:get / :post / ...), rails would know which method it has to use as the verbs are mapped to the methods. But when I state the whole path (controller and method), shouldn't rails know everything it needs without the verb? The form params are being sent anyway.
Update2
Ok, I've changed
get "/enrolments/:id/admin_comment" => "enrolments#admin_comment", as: "enrolments_admin_comment"
to
post "/enrolments/:id/admin_comment" => "enrolments#admin_comment", as: "enrolments_admin_comment"
Now everything works fine.
You'll be best looking at Rails' Resource Routing
HTTP Verbs
Each resources :controller you create in your routes.rb file creates a series of routes, which connect with relative HTTP Verbs:
The HTTP verbs part of the routing system is the most important, as it governs which controller action is loaded. You can use the same path helper with different HTTP Verbs to route to completely different controller actions
If you want to create a new path, you'd need to set the HTTP verb to method: :post, like this:
<%= form_for enrolment, :url => enrolments_admin_comment_path(enrolment), method: :post, remote: true do |f| %>
Routes
Perhaps you'd be better with this routing structure:
resources :courses do
resources :enrolments do
get :admin_comment, shallow: :true
end
end
With the HAML code:
%form{:action => "activate_foobar", :method => :post, :controller => "foobar", :url => activate_foobar_foobar_index_path}
%input{:type => "submit", :value => "Activate"}
The submit button directs to
No route matches "/activate_foobar"
rather than to "/foobar/activate_foobar". It does not seem to understand the url parameter.
Details
On the index page of foobar, there is a form which I'm trying to post to foobar_controller's method activate_foobar. Foobar does not have a model, as there is no such object - it is only a specialised property of Widget. (Widget has a model, and a method .activate_foobar)
activate_foobar_foobar_index is defined in routes as:
resources :foobar, :only => [:index] do
collection do
post :activate_foobar
end
end
:confirmed with rake:routes to be:
activate_foobar_foobar_index POST /foobar/activate_foobar(.:format) {:action=>"activate_foobar", :controller=>"foobar"}
:as expected.
Furthermore, experimentation with a simple:
=link_to "Activate", activate_foobar_foobar_index_path, {:method => :post}
:routed successfully to /foobar/activate_foobar
Within the confines of using a form (and not using simple_form_for or other model based solutions), how do you correct the path "foobar/activate_foobar"?
Sources:
I'm following http://guides.rubyonrails.org/routing.html "Adding more RESTful Actions" and http://www.w3schools.com/html/html_forms.asp to try to understand how to direct a form to the right method of the right controller.
Like you say it send the form to /activate_foobar, for some reason (maybe haml bug) it don't take the :controller param, to solve this in action write
:action => 'foobar/activate_foobar'
but you must be careful because it takes a relative route instead of absolute. So if you don't want to handle that issue I suggest you to change to rails form helper
= form_tag(activate_foobar_foobar_index_path, :method => :post) do
since activate_foobar is nested under foobar did you try doing
:url => activate_foobar_foobar_index_path(#foobar)
you need to tell rails where to look for the specific foobar to activate_foobar.
hope it helps.
I have the following route in my Rails3 project:
match "/blog/:permalink" => "posts#show", :as => :post
When I link to my post through a view as such:
<%= link_to #post.title, post_path(#post) %>
The id of the post is passed into the post_path helper (even though my route specifies the permalink is passed.
How do I force the post_path to send in the permalink instead of the id of the post?
I can explicitly call post_path(#post.permalink) but that seems dirty.
Am I missing something in my route?
Thanks!
Define a to_param method on the model that returns the string you want to use.
class Post < ActiveRecord::Base
def to_param
permalink
end
end
See this page, this Railscast, (and of course Google) for more info.
[Edit]
I don't think Polymorphic URL Helpers are smart enough to handle what you want to do here. I think you have two options.
1. Use a special named route and pass in the parameter similar to your question and Jits' answer.
match "/blog/:permalink" => "posts#show", :as => :post
and link to it
<%= link_to #post.title, post_path(:permalink => #post.permalink) %>
2. Create a new helper that generates the URL for you
match "/blog/:permalink" => "posts#show", :as => :post_permalink
and a helper
def permalink_to(post)
post_permalink_path(post.permalink)
end
and in your views
<%= link_to #post.title, permalink_to(#post) %>
Try something like this:
<%= link_to #post.title, post_path(:permalink => #post.permalink) %>
Rails should automatically construct the URL as per your routes (i.e. replacing :permalink accordingly).
In my application, I have a RecipesController and a CommentsController. All comments belong to a recipe, and can be voted up. Here's a snippet from my routes.rb:
resources :recipes do
member do
put 'vote_up'
post 'comment'
end
resources :comments do
member do
put 'vote_up'
end
end
end
If I run rake routes, I find the following route in the output:
vote_up_recipe_comment PUT /recipes/:recipe_id/comments/:id/vote_up(.:format) {:action=>"vote_up", :controller=>"comments"}
The CommentsController has a method called vote_up.
Also, linking to the route works (from my view)
<%= link_to 'Vote up', vote_up_recipe_comment_path(#recipe, comment), :method => 'put' %> <br />
However, clicking on that link gives me the following error:
Routing Error
No route matches "/recipes/7/comments/4/vote_up"
What am I missing? I'm not sure how to debug this, because as far as I can see the route should match.
I think that you get this error message because the request is made via HTTP GET method, not PUT.
In order to create links that use POST/PUT/DELETE method, your application should correctly load a Javascript Rails adapter.
Check that your app has jQuery (http://github.com/rails/jquery-ujs) or Prototype JS adapter and that your layout correctly loads it.
try the following tweak: send the put method as a symbol
<%= link_to 'Vote up', vote_up_recipe_comment_path(#recipe, comment), :method => :put %>