корневой путь для нескольких контроллеров на маршрутах рельсов - PullRequest
4 голосов
/ 31 марта 2012

У меня есть два контроллера ресурсов, где я использую слаг для представления идентификатора.(friendly_id gem).

Я могу указать путь показа для одного ресурса на маршруте, но не для двух одновременно.то есть.

root :to => 'home#index'
match '/:id' => "properties#show"
match '/:id' => "contents#show"

По сути, я хочу URL, как,

# Content
domain.com/about-us
domain.com/terms
# Property
domain.com/unique-property-name
domain.com/another-unique-property-name

Какой бы ресурс я ни поставил на верх, он работает.Есть ли способ сделать это?

Спасибо заранее, если вы можете помочь.

Ответы [ 5 ]

5 голосов
/ 09 апреля 2012

Это не проверено, но попробуйте использовать constraint на вашем маршруте.

root :to => 'home#index'
match '/:id', :to => "properties#show",
              :constraints => lambda { |r| Property.find_by_id(r.params[:id]).present? }
match '/:id', :to => "contests#show",
              :constraints => lambda { |r| Contest.find_by_id(r.params[:id]).present? }

В качестве альтернативы, вы можете создать отдельный класс, который будет отвечать на matches? вместо определения lambda proc.(Я рекомендую размещать эти классы в отдельных файлах, которые будут автоматически загружаться в вашем приложении Rails.)

# app/constraints/property_constraint.rb
class PropertyConstraint
  def self.matches?(request)
    property = Property.find_by_id(request.params[:id])
    property.present?
  end
end

# app/constraints/contest_constraint.rb
class ContestConstraint
  def self.matches?(request)
    contest = Contest.find_by_id(request.params[:id])
    contest.present?
  end
end

# config/routes.rb
root :to => 'home#index'
match '/:id', :to => "properties#show", :constraints => PropertyConstraint
match '/:id', :to => "contests#show", :constraints => ContestConstraint

К сожалению, это приводит к дополнительному запросу БД (один раз на маршрутах и ​​еще раз на вашем контроллере).Если у кого-то есть предложения по минимизации этого, пожалуйста, поделитесь.:)

2 голосов
/ 09 апреля 2012

Этот Rails Engine делает то, что вы хотите:

Slug Engine на Github

По сути, авторский подход заключался в монтировании Rails Engine внутри его основного приложения. Этот Engine включает в себя как контроллер для обработки существующих слагов, так и часть промежуточного программного обеспечения для фильтрации и воздержания от несуществующих слагов.

Он объясняет, почему он выбрал этот подход и другие прерванные решения, в довольно подробном и интересном сообщении в блоге . Этот пост в блоге и исходный код движка slug должны быть достаточно подробными для того, чтобы ваш собственный код заработал и работал, но этот движок с открытым исходным кодом, кажется, именно то, что вам нужно, если вы хотите решение для вставки. 1011 *

1 голос
/ 07 апреля 2012

Вы можете написать другой контроллер, который получает идентификатор от маршрутизатора и проверяет, принадлежит ли идентификатор свойствам или контенту, и отображает соответствующий вид.

match '/:id' => "router#show"

Контроллер будет делать что-то вроде этого:

def show
    @property = Property.find(params[:id])
    if @property then
        render 'property/show'
    else
        @content = Content.find(params[:id])
        render 'content/show
    end
end

Не тестировал этот код, но эта идея должна работать.

1 голос
/ 31 марта 2012

Вы можете сделать это в промежуточном программном обеспечении

  1. Обнаружить слаг в пути
  2. Если контент с этим слагом существует - измените путь запроса на «contents /: id»
  3. Если свойство с этим слагом существует - измените путь запроса на "properties /: id"
  4. в вашем наборе маршрутизации:

    соответствует свойствам содержимого /: id '=> "#show "

    match 'properties /: id' =>" contents # show "

0 голосов
/ 31 марта 2012

Я бы посоветовал вам сделать это более RESTful способом, если это возможно. По сути, у вас есть два разных ресурса, и вы должны разделить их:

match 'properties/:id' => "properties#show"
match 'contents/:id'   => "contents#show"

Это даст вам много преимуществ в будущем. Одним из непосредственных преимуществ является то, что вы можете избежать столкновений между идентификаторами свойств и контента. (Обратите внимание, что friendly_id не поможет вам в межмодельных столкновениях слагов в вашей первоначальной схеме.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...