2016-05-27 1 views
1

Я хочу объединить подобные методы и взгляды на один, но все же сохранить имя URL-адрес, как следующее:Как объединить много подобных методов и взглядов в один

Home/recommends/categories/shopping 
Home/recommends/categories/nightview 
Home/recommends/categories/food 
Home/recommends/categories/area 

Я не хочу использовать Params как "?something=xyz" в url.

В 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 } 

Может ли кто-нибудь помочь мне реорганизовать этот код?

ответ

3

Вы можете (и должны) иметь один маршрут, одно действие и один вид. Ключ должен превратить переменную часть вашего URL в действительную переменную . Вы делаете это, используя dynamic segments.

Во-первых, один маршрут. Там нет необходимости использовать resources, если вы на самом деле не генерировать множество RESTful действия:

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'