通过红宝石制作漂亮的网址

时间:2010-09-19 21:08:20

标签: ruby-on-rails ruby

好的,所以我希望事件的标题位于网址中

/events/party-at-mikes

所以这就是我的表现

Event.find_by_title(params[:title])

我的链接

 <%= link_to('<span>EVENTS</span>', course_event_path(obj.golf_course.city.permalink, obj.golf_course.permalink, obj.title), :class => 'right eve_bnt') %>

obj.title是事件

问题是网址看起来像这样

events/Party at mikes

我需要做些什么才能将 - 空间空间和查找捕获

放在空间中

4 个答案:

答案 0 :(得分:4)

你应该看看friendly_id宝石。它声称可以完全按照您的意图行事,并处理许多边缘情况。使这有点痛苦的主要边缘情况是:如果两个事件具有完全相同的标题怎么办?

忽略极端情况,正确的方法是重载两个类的方法:

class Event < ActiveRecord::Base
    ...

    # This is used automatically to build the :id component of the url
    # in the form /models/:id
    def to_param
        self.title
    end

    # Now assuming that you just use Event.find(params[:id]),
    # you probably want Event.find to work differently.
    def self.find(identifier)
        self.find_by_title(identifier)
    end

    ...
end

答案 1 :(得分:2)

Andres建议重写to_param以使用title,但这是不可接受的,因为你不需要空格等。你需要的是模型的永久链接或slug,存储在名为'slug'的字符串字段中以下示例。这是在保存记录时创建的,随后永远不会更改:这用作url中id的替换。 slug只有字母,数字和连字符,并且可以通过在末尾添加数字来强制它们是唯一的。然后,您更改to_param以使用slug,并通过slug在控制器中找到。例如

before_create :set_slug

def set_slug
  slug = self.title.downcase.gsub(/[^a-z0-9]/,"-")
  suffix = ""
  while self.class.find_by_slug(slug)
    slug.gsub!(/#{suffix}$/,(suffix == "" ? 1 : suffix+=1).to_s) 
  end
  self.slug = slug
end

def to_param
  self.slug
end

在您的活动控制器中

  before_filter :load_event, :except => [:index, :new]
...
protected
  def load_event
    @event = Event.find_by_slug(params[:id])
  end

答案 2 :(得分:1)

答案 3 :(得分:1)

我肯定会继续保持网址中的ID以及附加的友好名称。如果您的记录不好,这会使调试更容易,并且实现起来很简单。更不用说sql可以找到比varchar快得多的int。

将其放入您的模型中。无需定义段塞方法,因为这已经通过参数化在轨道中提供。它还具有需要对其他代码进行0更改的优点。这几乎适用于所有开箱即用的情况。


  # Slug the url.
  def to_param
    "#{id}-#{title.parameterize}"
  end