我正在开发的Rails应用程序中有许多不同的模型。我见过许多网站都使用了应用程序范围的slug路由方法。这是什么意思?
http://example.com/nick-oneill <-- This points to a User object
http://example.com/facebook <-- This points to a Company object
http://example.com/developers <-- This points to the users#index page
我知道to_param并在应用程序中创建了读者友好的slug,但是我不知道有一种方法可以为各种对象提供根级别的slu ..你可以认为这类似于Facebook的Graph API:有不同的对象类型,但它们都存在于https://graph.facebook.com/object-id
非常感谢任何见解!
答案 0 :(得分:10)
使用freindly_id可能有一种方法可以做到这一点,但我认为友好id的问题是由模型确定的范围。
如果我真的希望在整个网站上进行阻塞,我会创建一个与我所有模型具有多态关系的slugs表。
Sluggable_type和sluggable_id,然后是一个带有完整永久链/ slug的slug字段。
+---------------------------------------------+
| sluggable_type | sluggable_id | slug |
| user | 13 | users/john |
+---------------------------------------------+
现在我可以做一个通配符捕获所有路由或在运行时为我的所有slug创建路由,并在更新模型更新时强制路由刷新。
routes.rb
get "/*segments",
:controller => 'slugs',
:action => 'dynamicroute'
现在在你的SlugsController中实现一个类似
的方法def dynamicroute
segments = params[:segments]
slugs.find_by_slug(segments)
slug.sluggable_type.constantize.find(slug.sluggable_id) #retrive real record
#some magic to handle the slugged item maybe redirect to the appropriate
#controller or somehow call the show view for that controller
end
OR
routes.rb
begin
Slug.all.each do |s|
begin
get "#{s.slug}" => "#{s.sluggable_type.demodulize.pluralize.camelize}#show"
rescue
end
end
rescue
end
如果您使用第二种方法进行路由,请务必致电
YOUR_APP_NAME::Application.reload_routes!
编辑任何slugged记录后刷新路由表。
我们遇到过类似的问题,我们可能会尝试这种方法。
答案 1 :(得分:2)
我可能会按如下方式处理,至少作为第一遍:
/([-_a-zA-Z0-9]+)
的全能路线并将其指向EntitiesController#show
/developers
Users#index
建立更高优先级的路线
在EntitiesController中#show:
@entity = User.find(params[:id]) or Company.find(params[:id]) or raise ActionController::RoutingError.new('Not Found')
然后,根据你所拥有的实体类型:
render "VIEW_PATH_BASED_ON_ENTITY_CLASS/show"
我还会从大多数到最不经常访问的顺序排序(首先猜测,然后再使用数据来调整顺序)。
最后,可能很明显,但请确保您正在为每个表中的slug列编制索引,因为您经常会为每个请求执行多次查找。
FWIW我也想知道更好的方法来解决这个问题;这就是我最初如何解决问题的方法。
答案 2 :(得分:0)
我的第一反应是创建一个新的Slug模型。此模型将具有多态belongs_to
:
belongs_to :sluggable, :polymorphic => true
至少这个表会有:
value
- 或者更好的名字。 slu its本身的价值。sluggable_type
和sluggable_id
- 多态外键。您的公司,用户等型号模型只会有一个slu ::
has_one :slug
这给了我们一些优势:
resource
路由。您可能希望将其保留在路径文件的低端/末端,因此其他更具体的路由优先。 修改:此路由基本上是j_mcnally建议的第一个路由方法。就控制器的工作方式而言,我会选择Kyle所说的并关闭sluggable_type
字段来查找要渲染的视图。