ZK Zhao
ZK Zhao

Reputation: 21513

Rails: How to determine what page user is viewing?

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.

Upvotes: 0

Views: 673

Answers (4)

berkes
berkes

Reputation: 27553

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

Upvotes: 1

janfoeh
janfoeh

Reputation: 10328

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;
}

Upvotes: 0

toolz
toolz

Reputation: 891

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.

Upvotes: 2

griffon vulture
griffon vulture

Reputation: 6764

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.

Upvotes: 0

Related Questions