我的一些客户希望为Rails中的某些页面创建别名。下面显示了这种别名的一个示例:
match '/events_nl' => 'pages#show', :defaults => { :id => '1' , :locale => "nl"}
我们正在使用rails admin,所以如果我创建一个包含手动别名创建字段的表:
某些模型已经在表格中使用了别名,我们称之为模型页面。模型页面有一个字段别名,可以在路径中执行类似的操作:
pages_with_alias = Page.find_all_by_alias(true)
pages_with_alias.each do page
match page.alias , :to "pages#show", :defaults => { :id => page.id , :locale => page.locale}
end
问题: 我只是想找到最像这样做的铁路。
答案 0 :(得分:2)
执行此操作的典型方法是在路径文件末尾使用通配符路径,例如:
get '*alias', to: 'pages#show', as: :page
对于与任何其他路线不匹配的任何网址,将使用alias
参数中的路径调用PagesController的show动作。
然后在show动作中,您可以执行Page.find_by_alias!(params[:alias])
- 如果没有页面匹配,您将获得一个标准的404页面(因为将抛出ActiveRecord::RecordNotFound
异常),如果该页面是存在,那么你可以继续正常。
编辑:
对于您想要这样的别名的多个模型,您可以将通配符指向另一个控制器,然后在该控制器中迭代您的模型以查找匹配的模型。例如。第一个Page.find_by_alias(params[:alias])
....如果它是零,那么Testimonial.find_by_alias(params[:alias])
等......当你找到匹配的那个时,你就可以渲染出适当的视图。
当然,如果你这样做,你就冒着命名冲突的风险 - 如果你有一个推荐书和一个具有相同别名的页面会发生什么?一个永远不会被查看,因为另一个将被查找并首先匹配。
答案 1 :(得分:1)
在我亲爱的朋友七人的帮助下,一切都很顺利:
我做了什么:
1)向表中添加了所需的Alias字段/列
2)创建了Alias模型/控制器 此代码为伪代码,但您将获得图片
def show
object = Model.where("lower(alias) =?", params[:alias].downcase).first || OtherModel.where("lower(alias) =?", params[:alias].downcase).first
if object.class.name == "Model"
@model = Model.find_by_id!(object.model_id)
render "model/show"
elsif object.class.name == "OtherModel"
@othermodel = OtherModel.find_by_id!(object.othermodel_id)
I18n.locale = object.locale
render "othermodel/show"
else
not_found
end
end
3)创建路线
get '*alias', to: 'alias#show', as: 'alias'
仅供参考not_found:
def not_found
raise ActionController::RoutingError.new(t("activemodel.errors.messages.not_found"))
end
注1
这没有交叉表验证
谢谢大家的帮助:)
答案 2 :(得分:0)
未经测试,但这样的事情应该有用(如果你不介意做重定向,这在某些方面似乎更合适):</ p>
get '*alias', to: redirect { |params, request|
object = Page.find_by_alias(params[:alias]) || Other.find_by_alias(params[:alias])
Rails.application.routes.url_helpers.url_for(object)
}
您的方式可能更好如果(且仅当)您不需要动态更新路线(例如,您的解决方案不会有新的路径创建Page
对象,直到重新启动应用程序)。您可以将Rails.application.reload_routes!
作为模型观察的一部分,但这看起来并不干净。