Rails has generated this action url for my form:
<form action="/auth/failure?action=update&controller=users"...
I'm authenticated to the website, even If I shouldn't be, it would redirect somewhere as I understand Auth.
My Form code:
<%= form_for #user, :url => { 'controller' => 'users', 'action' => 'update'} do |f| %>
Thanks!
There is two thing you have to know
Ruby makes difference between symbols (:controller, :update) and strings ('controller', 'update').
You do not need to specify :url in this case.
So, for your current code, the correct line is simple:
form_for #user do |f|
If #user is a new record, form_for will point to create action of your UsersController, if #user is an existing record, form_for will point to update action automatically. Rails is smart enough to do this :-)
If you really want to use :url attribute of form_for, you have two option:
Use routing helper methods: form_for #user, :url => user_path(#user), :method => :put
Use a correct path hash: form_for #user, :url => { :controller => :users, :method => :update, :id => #user.id }
Rails uses REST style for building urls if you use resources :users in config/route.rb (and I recommend you to use that), and it have two thing you need to know:
- Collection is a group of entities (in your case, users)
- Member is one entity
So collection URL is something where you can expect multiple entities, member URL is something where you can expect only one entity.
You must use :id when you describe update action with URL-hash, because update can done only on member, not on collection. So you have to build a member URL with a special HTTP method (PUT) to clarify, what do you want to do.
Related
I have used link_to to call controller action.
<%= link_to "Inactive", {:controller => :leave_details, :action => :deactivate}, {:method => :post } %>.
but my requirement is to pass id also to controller action but when i try to pass id(:id=>leave_detail.id) it is not showing in params. my params look like
{"_method"=>"post", "authenticity_token"=>"3vfyGQ5V6GQXRt2aQt+DOT0b3eGgP7B401uclnIGLUU=", "action"=>"deactivate", "controller"=>"leave_details"}.
In route file i have added
resources :leave_details do
post :deactivate, :on => :collection
end
can anyone tell me what is going wrong in this code or what i am missing.
thnks
I am trying to generate a url in an actionmailer template. An example if the url I want to generate is
http://0.0.0.0:3000/users/confirm/lNbQxzFukYtEEw2RMCA
Where the last segment is a hash to identify the user
However when I use this
<%= url_for(:controller => 'users', :action => 'confirm', :id => #user.confirmhash, :only_path => false) %>
It generates this
http://0.0.0.0:3000/assets?action=confirm&controller=users&id=ZOR3dNMls8533T8hJUfCJw
How can I get it to correctly format? I have no idea where 'assets' is coming from.
Is there an easier way to use named routes that I am missing?
I've found the answer. As I'm still learning I've missed the option to create a named route. So this this the path I've taken.
In config/routes.rb
match 'user/confirm/:id' => 'users#confirm', :as => :confirm_account
Then in my action mailer template I've used
<%= link_to "Confirm your account", confirm_account_url(#user.confirmhash) %>
Which passes the :id into the controller action.
I'm trying to set up rails to use both the ID and the Handle (which is just an URL safe version of the title) of a blog post in the route.
match '/articles/:id/:handle', :to => 'articles#show'
resources :articles
This works, of course -- but I can't seem to set up the to_param method in the model os the longer URL -- with the handle attached, is the default.
This doesn't work (not that I really expected it to):
def to_param
"#{id}/#{handle}"
end
I get a No route matches {:action=>"edit", :controller=>"articles", error. I also tried just using the handle, but then Rails generates links to the resource just using the handle and not the ID. I know I can do it with a - in stead of a /, but I prefer the /. Any way to make this work? If I have to add some extra paremeters to my link_to helpers, that's okay.
Did you try to pass a Hash to link_to?
link_to "Link", {:id => #article.id, :handle => #article.handle}
Update
You have to modify your routes:
match '/articles/:id/:handle', :to => 'articles#show', :as => :article_with_handle
and use the following helper to generate the link:
link_to "Link", article_with_handle_path(:id => #article.id, :handle => #article.handle)
You can override the helper to simplify things:
def article_with_handle_path(article)
super(:id => article.id, :handle => article.handle)
end
and use it like this:
link_to "Link", article_with_handle_path(#article)
Okay, here's what I did to remove the query string problem from the answer above:
Changed the route to this:
match '/articles/:id/:handle' => 'articles#show', :as => :handle
Removed the to_param method from the model and then generated the link like this:
link_to 'Show', handle_path(:handle => article.handle, :id => article.id) %>
That works, but could be condensed, obviously, with the helper above. Just change the one line to: args[1] = handle_path(:id => args[1].id, :handle => args[1].handle)
OK, so Ive set up my mailer in Rails which works fine, but I wanted to make a new action (or maybe just a view?) to have a slimmed down contact form in a lightbox. I can do that all fine and dandy but it would use the default layout which I dont want. So I added:
render :layout => 'lightbox'
to the action so that I could use a new layout. Unfortunately that seems to block off my access to the model as I get this error when the lightbox pops up
undefined method `model_name' for NilClass:Class
#on this line
<% form_for #contact, :url => {:action => "create"}, :html => {:method => :post} do |f| %>
So by using a different layout I cant use the resources I set up in my routes which is here:
resources :contacts, :only => [:new, :create], :as => :contacts
#Im passing in a name to the email form
match "contacts/direct/:name" => "contacts#direct", :as => :direct_email
I hope that made sense. But what do I do?
In my config/routes.rb I have:
post "portal_plan_document/update"
rake routes confirms this:
$ rake routes
portal_plan_document_update POST /portal_plan_document/update(.:format) {:controller=>"portal_plan_document", :action=>"update"}
....
In my code I have:
<%= form_for #plan_doc,
:url => portal_plan_document_update_path,
:method => "POST", :remote => true do |f| %>
In my log file I see:
Started POST "/portal_plan_document/update" for 127.0.0.1 at 2011-03-31 18:04:37 -0400
ActionController::RoutingError (No route matches "/portal_plan_document/update"):
I am lost as what to do from here. Any help would be greatly appreciated!
I should state I am using Ruby 1.9.2 and Rails 3.0.5. Oh, I have restarted the server (WebBrick w/rails server) after updating routes.rb.
Jeremy
Figured it out! :)
if you have a non-empty object, rails assumes you want to update that object. i.e., use a 'PUT' instead of a 'POST'
to accomplish 'PUTs', rails will put a hidden input in the form, with "_method" = "put". so, it LOOKS like it's a POST, but rails is treating it as a PUT.
if you actually want to just update an object (what it looks like you're doing), a PUT is better, and you should just switch your routes over to PUT.
if (like I was), you're doing something that really requires a POST (i.e., it can't be sent more than once safely), you can write your form_for like this:
<%= form_for #plan_doc,
:url => portal_plan_document_update_path,
:html=>{:method => "POST"}, :remote => true do |f| %>
to confirm, look at the generated HTML source, and make sure the hidden "_method" field is not set to "put"
Try using that instead please :
:method => :post
If this does not still work, please lose the remote attribute and give it a try. Does it work without it ?
I had the same problem while upgrading a simple app from Rails 2 to Rails 3.
As you may guess I was updating all "remote_form_for(#item) (..)" helpers to "form_for :item remote => true (..)" syntax.
In my case this code from a items/_new.html.erb partial:
<%= form_for :item, :remote => true do |f| %>
<!--FIELDS-->
<% end %>
Gave me this error:
Started POST "/items/new" for 127.0.0.1 at Fri Aug 12 18:19:23
+0200 2011
ActionController::RoutingError (No route matches "/items/new")
As you can notice the method was a correct "POST", not a "PUT". The problem lied in the routing... I don't know why but when a remote POST method is sent by a partial, Rails routes the POST request to "/items/new" instead of "/items" route. Even if the purpose is to create a new "item" so the POST request should be correctly (and RESTfully) routed to "/items".
This code, with explicit action and controller, solved the problem:
<%= form_for :item, :remote => true, :url => { :controller => "items", :action => "create" } do |f| %>
<!--FIELDS-->
<% end %>