Is there a new syntax for `url_for` in rails 3? - ruby-on-rails-3

In a plugin helper, I have:
include Rails.application.routes.url_helpers
url_for(:only_path => true, :controller => 'people', :action => 'new')
Note that uses the new include syntax, that part works ok. But I get an error:
undefined local variable or method `controller' for #<ActionView::Helpers::InstanceTag:0x311ddf4>
Is there a new way to specify this, like maybe 'controller#action' ? what's the key?

url_for should work as usual, see http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-url_for
I checked it on my console:
ruby-1.9.2-head > include Rails.application.routes.url_helpers
=> Object
ruby-1.9.2-head > url_for(:only_path => true, :controller => 'admin/providers', :action
=> 'new')
=> "/admin/providers/new"
Maybe the error doesn't occur in the url_for because your error messages says ActionView::Helpers::InstanceTag this sounds like you're using some kind of Tag like link_to etc. Did you think about this?
Best regards
Simon

Related

url_for adding controller and action to querystring in rails 3.2

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.

Using generated paths with resources in Rails

I have following routes defined:
CyberTrackRails3::Application.routes.draw do
scope "(:locale)", :locale => /en|de|nl/ do
resources :login do
get 'index', on: :collection
get 'check', on: :collection
end
end
end
Now, url_for(:controller => 'login', :action => 'check'), gives me the correct url, en/login/check.
Using login_check_path however doesn't work. How do I make this work?
I've tried replacing get 'index', on: :collection with match 'check' => 'check' but that doesn't work. Neither does match 'check' => 'login#check'.
since you're adding an action to a resource, i think the automatically generated name is going to be reversed, ie 'check_logins_path' (see adding-more-restful-actions)
do you need login_check_path specifically? if so, you should be able to define the path outside of the resources :login block, ie
match '/login/check' => 'login#check', :via => :get, :as => 'login_check'
and like Fivell suggested, rake routes will show you the automatically generated name for a route.

Routing with id and handle in Rails

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)

How can I call different controllers from routes.rb

I'm just struggling a few hours with a problem, that seems rather easy, but not for me and not for google :)
I put some routes via
scope :path => '/:mandate_key', :controller => :tasks do
get '/' => :index #mandate_path
match '/import' => "import#index"
match '/clearance' => "clearance#index"
end
So far, so ugly! I'm looking for a way to call different controllers (import and clearance) dependent on the second param. Something like this:
scope :path => '/:mandate_key', :controller => :tasks do
get '/' => :index
scope :path => ':task_key', :controller => %{'task_key'}
get '/' => :index
end
end
where :task_key should be recognized as params[:task_key] and the called controller should be the value of params[:task_key]
So if a click a link like http://some.url/a_mandate_key/import it should call the ImportController.
I'm sure that the solution will be simple, but finding is hard!
Sometimes one is looking for a highly complicated solution, but it could be so much easier:
scope :path => '/:mandate_key' do
get '/' => "tasks#index" #mandate_path
get '/import' => "import#index"
get '/clearance' => "clearance#index"
end
Calling http://localhost/mandate the controller 'mandate' is called an params[:mandate_key] provides 'mandate'
Calling http://localhost/mandate/import the controller 'import' is called an params[:controller] provides 'import'
Trying the easy way is often the best way :)
Thanks for your help, Bohdan!
you might add in the bottom of your routes match ':controller(/:action(/:id))' so any unknown url will be dispatched this way
How about
scope :path => '/:mandate_key', :controller => :tasks do
get '/' => :index #mandate_path
end
....
match ':mandate_key/:controller(/:action)'
first scope will match routes /:mandate_key/tasks and the second one /:mandate_key/:controller or /:mandate_key/:controller/:action however second part should be defined in the bottom of your routes.rb file otherwise it'll match wrong routes

Rails url_for Gravatar routing error

This function is defined in the application_help.rb:
def gravatar_url_for(email, options = {})
url_for(
{
:protocol => 'http://',
:host => 'www.gravatar.com',
:controller => 'avatar',
# :controller => 'avatar.php',
:gravatar_id => Digest::MD5.hexdigest(email),
:only_path => false
}.merge(options)
)
end
It's used in views:
<%= image_tag(gravatar_url_for user.email, {:d => 'identicon', :s => 32, :r => 'g'}) %>
Occasionally, its usage will result in a routing error:
No route matches {:controller=>"avatar", :d=>"identicon", :r=>"g", :gravatar_id=>"486575e581db04b7c8ca218af8488657", :s=>32}
A valid email is being supplied when the error occurs.
If I replace the url_for() with this logic, it works as expected:
url_for("http://www.gravatar.com/avatar/" + Digest::MD5.hexdigest(email) + "?d=identicon&s=40&r=g")
** edit **
I had removed the following line from the routes.rb file:
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
match ':controller(/:action(/:id(.:format)))'
Is there a way to get the url_for to work without the 'legacy wild controller route'?
You might want to take a look at the Gravtastic plugin for Rails which supports Gravatar images in both Ruby and JavaScript.