0

For example, I have a footer

<%= link_to 'Tweets', tweets_path %>
<%= link_to 'Blogs', blogs_path %>

In the Tweets Index Page, I want to hide the <%= link_to 'Tweets', tweets_path %>. and show something else. How do I know what resource the user is currently on?

Specifically, I want to

resources = ['Tweet', 'Blog']   # get the model names, and there maybe something more to be added later
resources.each do  |resource|
  if controller.controller_name = resource  &&  controller.method_name = 'index'
      link_to new_resource_path  # for example, link_to new_tweet_path
  else 
      link_to resource_path   # for example, link_to tweets_path 
  end
end

The rough Idea is above. But in controller.controller_name and link_to method, I do not know the details of writing it.

I find controller.controller_name from Can I get the name of the current controller in the view? What would be a good way to do this?

UPDATE:

def footer_helper
  resources = ['tweet', 'blog']   # and perhaps something more
  resources.each do  |resource|
     if current_page?(controller: resource.pluralize, action: 'index')
        link_to "New #{resource.humanize}", {controller: resource.pluralize, action: 'new'}
      else
        link_to "#{resource.pluralize.humanize}", {controller: resource.pluralize, action: 'index'}
     end
  end
end

end

Now I've made it into a helper like above. But I find the .pluralize and .humanize irritating, is there any way to get rid of them?

Also, how can I use it in views? when I use <%= footer_helper %>, it shows ["tweet", "blog"]. It does not return properly.

Community
  • 1
  • 1
ZK Zhao
  • 19,885
  • 47
  • 132
  • 206

4 Answers4

2

params[:action] will show you what action they were routed too and likewise params[:controller] will find out which controller that action is in. You can use these to write some logic for your footer.

toolz
  • 871
  • 6
  • 12
1

Use the current_page? helper:

resources = ['tweet', 'blog']
resources.each do  |resource|
  if current_page?(controller: resource, action: 'index')
    link_to(resource.humanize, { controller: resource, action: 'new' })
  else 
    link_to(resource.humanize, { controller: resource, action: 'index' })
  end
end

This can be improved with the link_to_if helper:

resources = ['tweet', 'blog']
resources.each do  |resource|
  link_to_if(current_page?(controller: resource, action: 'index'), resource.humanize, {controller: resource, action: 'new'}) do
    link_to(resource.humanize, {controller: resource, action: 'index'})
  end
end

When you don't want the computer-gerenated interface texts (this often is a bad idea), consider making the resources a Hash, like so:

resources = {'tweets' => "Tweet", 'blogs' => "Blog"}
resources.each do  |resource, name|
  link_to_if(current_page?(controller: resource, action: 'index'), name, {controller: resource, action: 'new'}) do
    link_to(name, {controller: resource, action: 'index'})
  end
end
berkes
  • 26,996
  • 27
  • 115
  • 206
  • How can I pass `new_resource_path` to `link_to`? I mean, `resource` is just a string here. But I need to pass a `path` to the `link_to` method – ZK Zhao Dec 18 '13 at 12:10
  • Sorry, overlooked that. Edited! – berkes Dec 18 '13 at 12:12
  • Now I'm trying to make it into a Helper and use it in view. But the output has some problem, could you help me on this? I put it on the UPDATE – ZK Zhao Dec 18 '13 at 12:36
  • »But I find the .pluralize and .humanize irritating, is there any way to get rid of them?« Well, yes, by not attempting to create interface texts through code. See the update in my post. – berkes Dec 18 '13 at 13:47
0

There is a nice gem for it, for tidy code:

https://github.com/robotmay/link_to_active_state

This gem adds a small bit of extra functionality to the default Rails link_to view helper. It provides a very simple way of adding classes to links based on the current path.

Take a look.

griffon vulture
  • 6,594
  • 6
  • 36
  • 57
0

I use this method:

# application_helper.rb

module ApplicationHelper
  def body_id
    [body_class, params[:action]].join('-')
  end

  def body_class
    controller.class.to_s.gsub('Controller', '').underscore.dasherize.gsub('/', '-')
  end
end

In my layout:

# application.html.erb

<body id="<%= body_id %>" class="<%= body_class %>">
</body>

So for TweetsController#index, this renders

<body id="tweets-index" class="tweets">

Now you can apply CSS depending on the controller or controller action the user is on:

body#tweets-index a.tweet-links {
  display: none;
}
janfoeh
  • 10,243
  • 2
  • 31
  • 56