如何将许多类似的方法和视图合并为一个
How to Combine many similar methods and views into one
我想把相似的方法和观点合二为一,但还是保留url的名字,像下面这样:
Home/recommends/categories/shopping
Home/recommends/categories/nightview
Home/recommends/categories/food
Home/recommends/categories/area
我不想在 url 中使用像 "?something=xyz"
这样的参数。
在routes.rb
中:
resources :recommends, only: :index do
collection do
resources :categories, only: :show, controller: 'recommends' do
collection do
get :food
get :area
get :shopping
get :nightview
end
end
end
end
在控制器中:
def food
set_paginator
@recommends = UserRecommend.where(category: "food").order('created_at desc').offset(@offset).limit(@limit).all
@number_of_recommends = UserRecommend.where(category: "food").count
end
def area
set_paginator
@recommends = UserRecommend.where(category: "area").order('created_at desc').offset(@offset).limit(@limit).all
@number_of_recommends = UserRecommend.where(category: "area").count
end
...
我的观点是:
food.html.slim
area.html.slim
shopping.slim
nightview.slim
它们使用相同的代码,只是 h1
中的不同名称:
h1
| Shopping ( or Area or Food... )
= " (#{@number_of_recommends})"
= render partial: "layouts/paginator",
locals: { total_items: @number_of_recommends, per_page: @limit, current_page: @page }
= render partial: "table", locals: { recommends: @recommends }
谁能帮我重构这段代码?
您可以(并且应该)拥有单一路线、单一操作和单一视图。关键是要将 URL 的变量部分变成 实际变量 。您使用 dynamic segments.
执行此操作
首先,单一路线。如果您实际上没有生成多个 RESTful 操作,则无需使用 resources
:
get "/recommends/categories/:category" => "categories#show"
您可以为 :category
细分添加条件:
get "/recommends/categories/:category" => "categories#show", category: /food|area|shopping|nightview/
接下来,一个动作:
class CategoriesController < ApplicationController
before_action :set_paginator
def show
# params[:category] is "food"/"area"/etc
categories = UserRecommend.where(category: params[:category]).order('created_at desc')
@recommends = categories.offset(@offset).limit(@limit)
@number_of_recommends = categories.count
end
end
最后,单看:
# app/views/categories/show.slim
h1
= params[:category].capitalize
= " (#{@number_of_recommends})"
= render partial: "layouts/paginator",
locals: { total_items: @number_of_recommends, per_page: @limit, current_page: @page }
= render partial: "table", locals: { recommends: @recommends }
我认为最好使用本地化将 params[:category]
变成标题,这会给你更多的控制权,而不是依赖 URL 段的简单大写:
# app/views/categories/show.slim
h1
= t params[:category]
并且:
# config/locals/en.yml
en:
categories:
show:
food: 'Food'
area: 'Area'
nightview: 'Night View'
我想把相似的方法和观点合二为一,但还是保留url的名字,像下面这样:
Home/recommends/categories/shopping
Home/recommends/categories/nightview
Home/recommends/categories/food
Home/recommends/categories/area
我不想在 url 中使用像 "?something=xyz"
这样的参数。
在routes.rb
中:
resources :recommends, only: :index do
collection do
resources :categories, only: :show, controller: 'recommends' do
collection do
get :food
get :area
get :shopping
get :nightview
end
end
end
end
在控制器中:
def food
set_paginator
@recommends = UserRecommend.where(category: "food").order('created_at desc').offset(@offset).limit(@limit).all
@number_of_recommends = UserRecommend.where(category: "food").count
end
def area
set_paginator
@recommends = UserRecommend.where(category: "area").order('created_at desc').offset(@offset).limit(@limit).all
@number_of_recommends = UserRecommend.where(category: "area").count
end
...
我的观点是:
food.html.slim
area.html.slim
shopping.slim
nightview.slim
它们使用相同的代码,只是 h1
中的不同名称:
h1
| Shopping ( or Area or Food... )
= " (#{@number_of_recommends})"
= render partial: "layouts/paginator",
locals: { total_items: @number_of_recommends, per_page: @limit, current_page: @page }
= render partial: "table", locals: { recommends: @recommends }
谁能帮我重构这段代码?
您可以(并且应该)拥有单一路线、单一操作和单一视图。关键是要将 URL 的变量部分变成 实际变量 。您使用 dynamic segments.
执行此操作首先,单一路线。如果您实际上没有生成多个 RESTful 操作,则无需使用 resources
:
get "/recommends/categories/:category" => "categories#show"
您可以为 :category
细分添加条件:
get "/recommends/categories/:category" => "categories#show", category: /food|area|shopping|nightview/
接下来,一个动作:
class CategoriesController < ApplicationController
before_action :set_paginator
def show
# params[:category] is "food"/"area"/etc
categories = UserRecommend.where(category: params[:category]).order('created_at desc')
@recommends = categories.offset(@offset).limit(@limit)
@number_of_recommends = categories.count
end
end
最后,单看:
# app/views/categories/show.slim
h1
= params[:category].capitalize
= " (#{@number_of_recommends})"
= render partial: "layouts/paginator",
locals: { total_items: @number_of_recommends, per_page: @limit, current_page: @page }
= render partial: "table", locals: { recommends: @recommends }
我认为最好使用本地化将 params[:category]
变成标题,这会给你更多的控制权,而不是依赖 URL 段的简单大写:
# app/views/categories/show.slim
h1
= t params[:category]
并且:
# config/locals/en.yml
en:
categories:
show:
food: 'Food'
area: 'Area'
nightview: 'Night View'