Если я хочу переопределить путь к ресурсу (например, post_path (@post)), где я могу это сделать? - PullRequest
2 голосов
/ 16 мая 2011

ОБНОВЛЕНИЕ (снова) |Проигнорируйте вещь модуля - o я поднял здесь прежде.Лучше просто использовать to_param и заставить работать маршруты.

to_param
  if slug
    "#{id}-#{slug}"
  else
    super
  end
end

match "/posts/:id(-:slug)" => "posts#show", :as => :post, :constraints => { :id => /\d+|\d+-.*/ }

Хитрость в этом маршруте.Это делает -:slug необязательным и добавляет ограничение к :id.Предпочтение ограничения состоит в том, чтобы соответствовать только числовому значению (которое используется при поступлении запроса, поэтому в ваших параметрах есть :id и :slug), но канал позволяет ему также соответствовать числовому значению, за которым следуетпуля, с целью генерации маршрута.Это мягкий взлом, но все это правда.Разрешение ресурсом предоставить хэш параметров решит эту проблему.Это может быть применено к любому необычному маршруту, который вы хотите (например, с :id в конце вместо начала).

Rails 3.0.7.

Выберите маршрут, подобный:

match "/posts/:id-:slug" => "posts#show", :as => :post

Это предоставляет мне помощник post_path(obj), но, конечно, он хочет генерировать только один аргумент из моей модели, и из того, что я могу сказать, нет способа вернуть несколько значений из моих моделей.to_param метод.Я знаю, что могу написать to_param так:

to_param
  "#{id}-#{slug}"
end

Но это передается как один аргумент для маршрута, который в конечном итоге не соответствует ни одному из маршрутов.Точно так же я знаю, что могу удалить "-:slug" из моего маршрута, но тогда параметр :id содержит фиктивный ввод и, по сути, является чем-то вроде хака (хотя, очевидно, дело сделано).

Было быбыло бы здорово, если бы будущая версия Rails позволила вам вернуть хеш от to_param, например:

to_param
  { :id => id, :slug => slug }
end

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

What I'mпытаясь выяснить, где я могу переопределить post_path(), чтобы обеспечить правильный маршрут.Я могу поместить его в помощник вида, но тогда он не будет доступен в моих контроллерах, поэтому я предполагаю, что это неправильное место для этого.

Просто любопытно больше всего на свете.Я знаю, что это нормально работает, если я просто опускаю :slug на маршруте, но в более сложной ситуации я могу представить, что переопределение путей по умолчанию было бы полезно знать.Возможность генерировать маршрут, просто передавая ресурс, является довольно приятной функцией, которую я хотел бы принять, но отдел маркетинга всегда будет заставлять нас заполнять URL-адреса всевозможными ключевыми словами.

1 Ответ

4 голосов
/ 16 мая 2011

У маршрутизации есть две стороны: маршрут генерация и маршрут соответствие .

Генерация маршрута , как вы указали,довольно легко.Переопределить to_param в любой ActiveModel:

# In a model:
def to_param
  # Use another column instead of the primary key 'id':
  awesome_identifier.to_s
end

Совпадение маршрута менее очевидно.Можно указать :awesome_identifier вместо каждого вхождения :id в маршрутах ресурсов по умолчанию.Однако я обнаружил, что Rails окажет вам меньшее сопротивление, если вы оставите :id на своих маршрутах, а только изменит логику в вашем контроллере .Обратите внимание, что это компромисс, потому что принципиально :id в ваших маршрутах не совсем корректен.

# In a controller:
def index
  @awesome_record = AwesomeModel.find_by_awesome_identifier(params[:id])
  # ...
end

Как вы заметили, Rails оптимизировал для одного варианта использования : если вы хотите, чтобы первичный ключ использовался для быстрого поиска записей, но при этом предпочитаете, чтобы слаг был включен в URL для удобства пользователя или оптимизации поисковой системы.В этом случае вы можете вернуть строку вида "#{id}-#{whatever}" из метода to_param, и все, что находится после тире, будет игнорироваться при подаче той же строки обратно в метод find.

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