我想为由acts_as_taggable_on gem管理的标签创建url slugs。例如,我不想使用http://myapp.com/tags/5这样的网址,而是http://myapp.com/tags/my-tag(其中'我的标记'是标记的唯一名称)。
在我自己创建的模型中,我通常通过覆盖模型的to_param方法,并在模型中创建“slug”字段来保存新的to_param方法的结果。我尝试使用ActsAsTaggableOn的Tag模型执行此操作,但它无效。
我可以覆盖ActsAsTaggableOn的tag.rb类中的内容,如下所示:
# Overwrite tag class
ActsAsTaggableOn::Tag.class_eval do
def name
n = read_attribute(:name).split
n.each {|word| word.capitalize!}.join(" ")
end
end
但是,如果我尝试使用如下方法定义覆盖同一块中的to_param方法:
def to_param
name.parameterize
end
Rails仍会生成并响应具有整数ID的路由,而不是参数化名称。事实上,如果我尝试像
那样在控制台中ActsAsTaggableOn::Tag.find(1).to_param
返回整数ID,而不是重写的to_param方法的结果。
如果有任何方法可以使用我自己的应用程序代码,我宁愿不分叉gem并自定义它。感谢。
答案 0 :(得分:14)
@ vitork的代码是一个良好的开端,但对于较新版本的friendly_id和acts_as_taggable不起作用。这是一个更新的初始化程序:
ActsAsTaggableOn::Tag.class_eval do
extend FriendlyId
friendly_id :name,
:use => :slugged,
:slug_column => :permalink,
:reserved_words => ['show', 'edit', 'create', 'update', 'destroy']
end
我的db列名为永久链接,如果您愿意,可以使用 slugged 。顺便说一下,我正在使用以下内容:
感谢Vitork的初始代码!
答案 1 :(得分:13)
我正在使用friendly_id(https://github.com/norman/friendly_id)gem来管理slu ..我为我的标签创建slugs的方法与你的类似,但更简单一点。
我刚刚使用以下代码创建了初始化程序act_as_taggable_on.rb:
# act_as_taggable_on.rb
ActsAsTaggableOn::Tag.class_eval do
has_friendly_id :name,
:use_slug => true,
:approximate_ascii => true,
:reserved_words => ['show', 'edit', 'create', 'update', 'destroy']
end
然后:
@user = User.new :name => "Jamie Forrest"
@user.tag_list = "This is awesome!, I'm a ruby programmer"
@user.save
瞧瞧:
ActsAsTaggableOn::Tag.find('this-is-awesome') #=> #<Tag id: 1, name: "This is awesome!">
ActsAsTaggableOn::Tag.find('im-a-ruby-programmer') #=> #<Tag id: 2, name: "I'm a ruby programmer">
希望这有帮助...
答案 2 :(得分:9)
实际上答案要简单得多,你不需要使用friendly_id或任何其他不必要的扩展。
сonfig/初始化/ act_as_taggable_on.rb
ActsAsTaggableOn::Tag.class_eval do
before_save { |tag| tag.slug = name.parameterize if name_changed? }
def to_param
slug
end
end
如果需要,添加一个slug列,否则跳过before_save回调。
然后在视图中,而不是像
那样迭代article.tag_list.each do |tag|..
你会像这样迭代
article.tags.each
因为tag_list只给你字符串,而有标签你有真正的标签实例。 至少在控制器中
if params[:tag]
tag = ActsAsTaggableOn::Tag.find_by_slug(params[:tag])
@articles = Article.moderated.includes(:user).tagged_with(tag)
end
答案 3 :(得分:8)
要使用最新版本(Rails 4.x,friendly_id 5.x),请执行以下步骤:
# rails generate migration add_slugs_to_tags
class AddSlugToTags < ActiveRecord::Migration
def change
add_column :tags, :slug, :string
add_index :tags, :slug
end
end
您可以重命名:slug列 - 如果更改它,则应在初始化程序中指定列名。不要忘记运行迁移rake db:migrate
。
# config/initializers/acts_as_taggable_on.rb
ActsAsTaggableOn::Tag.class_eval do
extend FriendlyId
friendly_id :name, use: :slugged
end
搜索代码时,您必须使用ActsAsTaggableOn::Tag.friendly.find 'tag-name'
或将:finders
添加到friendly_id:使用调用直接在模型上使用find。阅读friendly_id guides中的更多内容。
答案 4 :(得分:1)
还有另一种方式。
使用单个操作为标记创建控制器:
rails g controller tags index
在 routes.rb 中,将生成的路线更改为:
get 'tags/:tag' => 'tags#index', as: :tag
在 tags_controller.rb 中添加以下代码:
def index
@tag = params[:tag]
@entries = Entry.tagged_with(@tag)
end
其中Entry
是型号名称。
现在您可以使用 example.com/tags/animals
等精美网址获取所有条目视图中的用法:
- @entry.tags.each do |tag|
= link_to tag, tag_path(tag.name)