1

I am using Ruby on Rails 3.0.9 and I would like to know why I get the error described below and how can I solve that.

In my /views/articles/categories/_content.html.erb file I have:

...
<%= link_to("New article", {:controller => content[:article_controller], :action => 'new'}) %>
...

If I set the content[:article_controller] to (both setting true and false for the :only_path option)

 1. content[:article_controller] = 'articles'
 2. content[:article_controller] = '/articles'
 3. content[:article_controller] = '/articles/'
 4. content[:article_controller] = '/'
 4. content[:article_controller] = ''

I get respectively the following errors (note :controller values):

 1. `ActionView::Template::Error (No route matches {:controller=>"articles/categories/articles", :action=>"new"})`
 2. `ActionView::Template::Error (No route matches {:controller=>"articles//articles", :action=>"new"})`
 3. `ActionView::Template::Error (No route matches {:controller=>"articles/", :action=>"new"})`
 4. `ActionView::Template::Error (No route matches {:controller=>"articles//", :action=>"new"})`
 4. `ActionView::Template::Error (No route matches {:controller=>"articles/categories/", :action=>"new"})`

Is it a Ruby on Rails bug or is it my fault? What is the problem and how can I solve that making the link_to properly work?

However I can solve that problem by using:

<%= link_to("New article", {:controller => '../', :action => 'new'}) %>

But why it works with '.../' but not in other ways?


I noticed that some time the controller path for which I try to set the content[:article_contr8oller] seems to relying on the "base" current controller path that is handling the view file (the controller file is app/controllers/articles/categories/concerns_controller.rb - read below for more information)... why it happens?

It also happens using url_for:

url_for(:controller => 'articles', :action => 'new')

Running the rake routes command I get the following:

   articles_categories GET    /articles/categories(.:format)          {:action=>"index", :controller=>"articles/categories"}
                       POST   /articles/categories(.:format)          {:action=>"create", :controller=>"articles/categories"}
 new_articles_category GET    /articles/categories/new(.:format)      {:action=>"new", :controller=>"articles/categories"}
edit_articles_category GET    /articles/categories/:id/edit(.:format) {:action=>"edit", :controller=>"articles/categories"}
     articles_category GET    /articles/categories/:id(.:format)      {:action=>"show", :controller=>"articles/categories"}
                       PUT    /articles/categories/:id(.:format)      {:action=>"update", :controller=>"articles/categories"}
                       DELETE /articles/categories/:id(.:format)      {:action=>"destroy", :controller=>"articles/categories"}
              articles GET    /articles(.:format)                     {:action=>"index", :controller=>"articles"}
                       POST   /articles(.:format)                     {:action=>"create", :controller=>"articles"}
           new_article GET    /articles/new(.:format)                 {:action=>"new", :controller=>"articles"}
          edit_article GET    /articles/:id/edit(.:format)            {:action=>"edit", :controller=>"articles"}
               article GET    /articles/:id(.:format)                 {:action=>"show", :controller=>"articles"}
                       PUT    /articles/:id(.:format)                 {:action=>"update", :controller=>"articles"}
                       DELETE /articles/:id(.:format)                 {:action=>"destroy", :controller=>"articles"}

P.S.: If you need more information, let me know and I will update the question as well.


UPDATE I

In my route file I have:

namespace :articles do articles :categories end

scope :path => 'articles/categories/:id', :controller => 'articles/categories/concerns' do
  ...
end

resources :articles

UPDATE II

In my view /views/articles/categories/_content.html.erb files I have:

<div class="links">
  <%= link_to("New article", {:controller => content[:article_controller], :action => 'new'}) %>
</div>

In my Articles::Categories::ConcernsController (that is, in the app/controllers/articles/categories/concerns_controller.rb file) I have:

def show
  @articles_category = Articles::Category.find(params[:id])

  respond_to do |format|
    format.html {
      render :partial => '/views/articles/categories/_content.html.erb',
        :locals  => {
          :content => {
             :article_controller => '/articles'
          }
        }
        format.js  {
          ...
        end
  end
end
Backo
  • 18,291
  • 27
  • 103
  • 170

2 Answers2

0

Did you try using symbols? I think they are more "direct".

<%= link_to("New article", {:controller => content[:article_controller].to_sym, :action => :new}) %>

Did you try using a relativ path?

<%= link_to("New article", {:controller => "../#{content[:article_controller]}", :action => 'new'}) %>
Koraktor
  • 41,357
  • 10
  • 69
  • 99
  • String or symbol it doesn't matter, nor does a relative path – Ryan Bigg Jul 29 '11 at 05:11
  • @Koraktor - Using symbols I get the following error: 'ActionView::Template::Error (can't convert Symbol into Integer)'. Using relative paths I get the following error: 'ActionView::Template::Error (No route matches {:controller=>"articles/../articles", :action=>"new"})' – Backo Jul 29 '11 at 05:20
  • @Backo, when using a url hash, the controller needs to be the name of the controller, not a path. The whole point of building the url from a hash (or preferably from a named route) is that you don't have to worry about relative paths. – Jeremy Weathers Jul 29 '11 at 05:23
  • @Jeremy Weathers - I set the name of the controller (not its path). – Backo Jul 29 '11 at 05:29
  • @Backo, neither of these examples from your question `'/articles/'` and comment `:controller=>"articles/../articles"` are controller names - both are paths. That is why they don't work. I have no idea why you have multiple controllers for creating new articles, but if that's what you are doing, then you either need to pass a valid controller name (e.g. 'articles' refers ArticlesController defined in app/controllers/articles_controller.rb), or build the root-relative URL manually. Again, it seems like you're fighting Rails here, but feel free to provide more complete explanations. – Jeremy Weathers Jul 29 '11 at 05:41
0

Why aren't you using link_to 'New article', new_article_path? Why use the old, tired url_for ... when you can use the named path/url helper (new_article_url).

Jeremy Weathers
  • 2,556
  • 1
  • 16
  • 24
  • It is because I am passing some ':locals' variable to a partial template file. – Backo Jul 29 '11 at 05:27
  • You have more than one controller that manages articles? Why? I'm sensing some weird, possibly smelly code that you haven't shown. – Jeremy Weathers Jul 29 '11 at 05:32
  • Yes, you are right, but other controllers do not manages the Article class. Furthermore, the mentioned Category class is namespaced and it is just stated in routes before Article related routers. Can be it the problem? What information do you need to know (I wrote that in the question at *P.S.*) – Backo Jul 29 '11 at 05:39