我有一项任务是按照路由模型开发rails应用程序。
我需要PageController
和Page
型号。网页网址必须与/contacts, /shipping, /some_page
相似。
我还需要CatalogController
和Category
型号。类别网址必须与/laptops, /smartphones/android
类似。
它将是ProductsController
和Product
型号,产品网址必须为/laptops/toshiba_sattelite_l605
行,/smartphones/android/htc_magic
我了解使用
等网址可以解决此问题/page/shipping
/catalog/smartphones/android
但客户不希望在网址中看到“/page
”或“/catalog
”的插入。
请告诉我解决这个问题的方向。 抱歉我的英语不好。
答案 0 :(得分:49)
你必须写一个“包罗万象”的规则:
在routes.rb上:
get '*my_precioussss' => 'sauron#one_action_to_rule_them_all'
贵重的控制者:
class SauronController < ApplicationController
def one_action_to_rule_them_all
@element = find_by_slug(params[:my_precioussss])
render @element.kind # product, category, etc
end
end
然后为每个元素的“种类”写一个视图:product.html.erb,category.html.erb等。
确保编写find_by_slug
实施。
您可以将one_action_to_rule_them_all
更改为pikachu_i_choose_you
,将SauronController
更改为PokemonController
也可以。
答案 1 :(得分:4)
你需要写一个全部的
match '*page' => 'pages#show'
然后处理页面控制器中的页面路径
def show
if params[:page]
@page = Page.find_by_page(params[:page])
else
@page = Page.find(params[:id])
end
...
如果您使用Omniauth或其他使用它自己捕获的rails lib,您可能需要从中排除一些URL,在约束中使用lambda
match '*page' => 'pages#show', :constraints => lambda{|req| !req.env["REQUEST_URI"].include? "auth"}
如果你想拥有嵌套路径(例如“smartphones / android”),你需要将:page param分开并处理控制器中的路径段
path = :page.split("/") // you now have an array of path segments you can use in your controller
答案 2 :(得分:1)
我发现rails 3路由指南非常有帮助:
http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/
答案 3 :(得分:1)
我已经结合两种方法完成了它
使用friendly_id gem在查找请求中使用slug而不是数字ID
定义:constraints=>ConditionClass
的路由,必须返回true
或false
(因此路由将被确定)
小例子:
#routes.rb
class CategoryBrandGoodConstraint
def self.matches?(request)
path_parts = request.path.split('/')
Category.find(path_parts[1]).present?&&Brand.find(path_parts[2]).present?&&Good.find(path_parts[3]).present? rescue false
end
end
get ':category_friendly_id/:brand_friendly_id/:good_friendly_id' => 'goods#index', :constraints => CategoryBrandGoodConstraint
#another conditional routes with another :constraints=>ConditionClass2 definition
#...
#until you define all necessary conditional application routes
#goods_controller.rb
def index
#operate with params[:category_friendly_id], params[:brand_friendly_id], params[:good_friendly_id] to collect all you need for view rendering
end
当然,您可以路由到另一个控制器以呈现另一个视图get '/:whatever' => 'another_controller#another_action', :constraints=>ConditionClassN
欢呼声
答案 4 :(得分:0)
Rails路由仅基于URL。如果您在名称之前没有/pages
或/categories
或其他任何内容,那么Rails如何判断http://example.com/smartphones
之类的网址是否为网页网址或类别网址?除非您在路线条件中有一些预定义的页面名称列表,否则它不能。
在此示例中,唯一的方法是按smartphones
实际搜索页面,如果没有找到,则假设这是类别名称并搜索类别。这不能在rails路由中完成。要做到这一点,你需要一个控制器来处理所有这些URL并进行搜索,然后渲染一个合适的模板(你不能重定向,因为这会改变网址)。这是解决这个问题的一种丑陋方式。
如果我是你,我会试图说服客户就某种前缀(如/p_pagename
)或最好是不同的网址达成一致。它可能类似/p/shipping
页面,所有其他网址可以路由到CategoriesController
或ProductsController
。