One link method fits all

Today I’ve created a universal rails helper to deal with multiple models of a multi-language project in a common way:

def link_to_add(object, args={})
  return '' unless logged_in?
  object = [object] unless object.is_a?(Array)
  link = link_to(t("#{object.last.to_s}.add"), new_polymorphic_path(object, args))
  content_tag :p, link
end

def link_to_edit(object, args={})
  return '' unless logged_in?
  object = [object] unless object.is_a?(Array)
  return '' if object.last.new_record?
  node = object.last.class.to_s.underscore
  link = link_to(t("#{node}.edit"), edit_polymorphic_path(object, args))
  content_tag :p, link
end

def link_to_delete(object)
  return '' unless logged_in?
  object = [object] unless object.is_a?(Array)
  return '' unless object.last.persisted?
  node = object.last.class.to_s.underscore
  link = link_to(t("#{node}.delete"), object, 
    data: { method: 'delete', confirm: t("#{node}.delete?") })
  content_tag :p, link
end

Now all links to create, edit or delete an instance look nice and intuitive.

I type short

<%= link_to_add :post %>

instead of long

<% if logged_in? %>
  <p><%= link_to t('post.add'), new_post_path %></p>
<% end %>

It handles nested routes. Just type

<%= link_to_edit [@post, @comment] %>

instead of

<% if logged_in? %>
  <p><%= link_to t('comment.edit'), edit_post_comment_path(@post, @comment) %></p>
<% end %>

And my favourite one:

<%= link_to_delete [@post, @comment] %>

instead of

<% if logged_in? %>
  <p><%= link_to t('comment.delete'), [@post, @comment],
    data: { method: 'delete', confirm: t('comment.delete?') } %></p>
<% end if @comment.persisted? %>

Published on December 09, 2009 (over 7 years ago)

Article tags: helper, links, rails

Comments (1)

Paul Philippov 14 days ago

Scrap it. I don't think it's a good idea, after all =)