JasonDaly.name

PHP, Ruby, Symfony, Rails, Doctrine, MooTools. Web Development.

Posts tagged with "RoR"

May 19, 2011

Using intern to Reference Routes Dynamically

In config/routes.rb if routes such as the following exist:

match "users/customers" => "users#customers", :as => :users_customers, :via => :get
match "users/employees" => "users#employees", :as => :users_employees, :via => :get 

match "users/:id/toggle-status" => "users#toggle_status", :as => :users_toggle_status, :via => :put

the views associated with the :users_customers and :users_employees actions above (in this case each displaying a list-view of users of the specified type) likely both have a link referencing the :users_toggle_status route.

Within the toggle_status action the route to redirect back to can be determined by looking at the type of user who’s status is being toggled. A sample version of this action is below.

def toggle_status
    user = User.find(params[:id])
    user.toggle_status!

    if user.type == 'employee'
      redirect_to :users_employees and return
    end

    redirect_to :users_customers and return
end

The condition above and multiple redirect_to’s is cumbersome and unnecessary. Instead, we can use Ruby’s intern method for strings.

def toggle_status
    user = User.find(params[:id])
    user.toggle_status!

    redirect_to ('users_%s' % user.type).intern and return
end

11 notes Tags: ruby rails ruby on rails RoR intern string tips code

April 26, 2011

Reverse Pagination Count with Kaminari

When displaying a threaded conversation with messages paginated by Kaminari, I had the unique requirement to display messages in DESC order by their creation date. This meant that if there were 12 messages with 5 per page, the breakdown would be

  • Page 1: messages 12 - 8
  • Page 2: messages 7 - 3
  • Page 3: messages 2 - 1

To actually display the message number next to each message, it had to be calculated using the methods added to a paginated model by Kaminari (see the :message_number value below)

<div class="comments">
  <% @messages.each_with_index do |message, index| %>
    <%= render :partial => 'message', :locals => {:message => message, :message_number => @messages.total_count - (@messages.current_page - 1) * @messages.limit_value - index} %>
  <% end %>
</div>

For now this is the only place the above calculation is relevant. Should I need it in multiple places I would move the above calculation to a helper.

3 notes Tags: rails ruby on rails RoR code tips ruby kaminari

April 25, 2011

Parsing and Pluralizing Model Names in Rails

Recently working with Kaminari, I wanted to have text display next to the pagination links like

283 Items - Page 3/15

I wanted the Items text to be dynamic according to the model the paginated collection was representing. Looking over my model names I found converting each to a human readable version would work great in all cases I needed a paginator. Simply using pluralize (I use singular form for my models) will not work in all cases.

  • User would become Users - great!
  • Page would become Pages - great!
  • ConversationMessage would become ConversationMessages - yuck!

For the ConversationMessage model, I really only wanted to display the items in the collection to the user as Messages, not ConversationMessages or even Conversation Messages. I found this was common for my other models on the many side of a one-to-many relationship too (ie. for my UserComplaint model, I wanted the pagination text to say simply Complaints).

The following works beautifully for all models I currently have in place

@collection.first.class.name.underscore.humanize.pluralize.titleize[/\s?([^\s]+)$/, 1]

With models having their default names (in the plural form), the .pluralize call can be removed.

4 notes Tags: ruby ruby on rails rails RoR code tips Kaminari pagination paginator