同一控制器的自定义路由。我的应用程序中有许多半静态页面(实际上存储在我的数据库中,包含组和页面名称字段),它们按产品分组,然后按主题分组,例如 汽车:轮胎,车轮,收音机,挡风玻璃 家园:门,窗户,屋顶 产品和服务:数据服务
我不想为每个组制作新的控制器。但是,我试图获得描述性的不同URL路径。例如:
domain.com/cars/tires_and_spokes
domain.com/cars/wheels
domain.com/homes/doors_and_knobs
domain.com/homes/windows
domain.com/products_and_services/data_service
目前,我所拥有的只是
domain.com/pages/cars_tires_and_spokes
etc.
但我更喜欢前者。
路线:
pages_from_DB =[
{group:"cars", name:"tires and spokes"}
{group:"cars", name:"wheels"}
{group:"homes", name:"tires and spokes"}
{group:"homes", name:"windows"}
]
pages = %w[
cars_tires_and_spokes
cars_wheels
homes_doors_and_knobs
homes_windows
products_and_services_data_service
]
pages.each do |page|
get page, controller: "pages", action: page
end
控制器:
class PagesController < ApplicationController
pages_from_DB =[
{group:"cars", name:"tires and spokes"}
{group:"cars", name:"wheels"}
{group:"homes", name:"tires and spokes"}
{group:"homes", name:"windows"}
]
pages = %w[
cars_tires_and_spokes
cars_wheels
homes_doors_and_knobs
homes_windows
products_and_services_data_service
]
pages.each do |page|
define_method(page) do
end
end
end
答案 0 :(得分:2)
看起来你已经错过了nested resources
:
#config/routes.rb
resources :groups, path: "", only: [] do
resources :pages, path: "" #-> url.com/:group_id/:id
end
这会将任何用户定向到pages
控制器,他们可以从他们各自的模型中提取Group
和ID
:
#app/controllers/pages_controller.rb
class PagesController < ApplicationController
def show
@group = Group.find params[:group_id]
@page = @group.pages.find params[:id]
end
end
-
这应该伴随以下模型:
#app/models/group.rb
class Group < ActiveRecord::Base
has_many :pages
end
#app/models/page.rb
class Page < ActiveRecord::Base
belongs_to :group
end
如果您想使用slug
(而不是id
)处理路线,则需要查看friendly_id
:
#Gemfile
gem "friendly_id"
$ rails generate friendly_id
$ rails generate scaffold group title:string slug:string:uniq
$ rails generate scaffold page title:string slug:string:uniq
$ rake db:migrate
#app/models/group.rb
class Group < ActiveRecord::Base
has_many :pages
extend FriendlyId
friendly_id :title, use: [:slugged, :finders]
end
#app/models/page.rb
class Page < ActiveRecord::Base
belongs_to :group
extend FriendlyId
friendly_id :title, use: [:slugged, :finders]
end
这将允许您使用:
<%= link_to group_pages_path(@group, @page) %>
# -> url.com/group-name/page-title
<强>更新强>
上面的代码基于这样的想法,即您可以将pages
放入数据库中(如您所愿)。如果您不想这样做,
#config/routes.rb
get "*group/:page", to: "pages#show"
如果页面是“半静态的”(仍然不知道这意味着什么),那么您就可以根据需要呈现各种视图:
#app/controllers/pages_controller.rb
class PagesController < ApplicationController
def show
group = params[:group]
render "#{params[:group]}/#{params[:page]"
end
end
以上内容将为您提供以下链接:
url.com/path/to/your/group/this-is-the-page-id
根据您的组/子组结构,它应该能够调用各种视图。我不同意它,但它显然是你想要的。
-
自定义中间件
我们还创建了具有部分功能的自定义中间件:
#config/routes.rb
get "*group/:page", to: PageDispatcher.new
#app/controllers/pages_controller.rb
class PagesController < ApplicationController
cattr_accessor :pages #-> PagesController.pages
@@pages = %w[
cars_tires_and_spokes
cars_wheels
homes_doors_and_knobs
homes_windows
products_and_services_data_service
]
end
#lib/page_dispatcher.rb
class PageDispatcher
#Init
def initialize(router)
@router = router
end
#Env
def call(env)
group = env["action_dispatch.request.path_parameters"][:group]
page = env["action_dispatch.request.path_parameters"][:page]
if PagesController.pages.include? page
strategy(slug).call(@router, env)
else
raise ActiveRecord::RecordNotFound
end
end
##########################################
private
#Strategy
def strategy(url)
Render.new(url)
end
####################
#Render
class Render
def initialize(url)
@url = url
end
def call(router, env)
controller = PagesController
action = "show"
controller.action(action).call(env)
end
end
####################
end