url_for пользовательского УСПОКОИТЕЛЬНОГО ресурса (составной ключ; не просто идентификатор)

Учитывая следующее определение ресурса:

map.resources :posts, :except => [:show]
map.post '/:year/:month/:slug, :controller => :posts, :action => :show

Я могу сделать url_for работа для меня, с помощью этого синтаксиса:

<%= link_to @post.title, post_url(:year => '2010', :month => '02', :slug => 'test') %>

Но есть ли способ сделать эту работу?

<%= link_to @post.title, @post %>

В настоящее время это бросает эту ошибку:

No route matches {:year=>#<Post id: 1, title: "test", (...)>, :controller=>"posts", :action=>"show"}

По-видимому, это передает объект @post первому параметру маршрута (походит на ошибку направляющих...). Но я могу сделать эту работу для меня? Я добавлю то питание с default_url_options тупик.

Решение, работающее только в направляющих 3.x, в порядке, но я предпочел бы не использовать любые плагины.

9
задан Paweł Gościcki 17 February 2010 в 18:44
поделиться

3 ответа

Как насчет исправления url_for для PostsController ? Может быть, не очень элегантно, но он СУХОЙ, и все должно работать.

# app/controllers/posts_controller.rb 
class PostsController < ApplicationController

  protected

    def url_for(options = {} )
      if options[:year].class.to_s == "Post"
        obj = options[:year]
        options[:year] = obj.year
        options[:month] = obj.month
        options[:slug] = obj.slug
      end
      super(options)
    end

end
6
ответ дан 4 December 2019 в 13:01
поделиться

Переопределить to_param . Значение по умолчанию для to_param - это идентификатор записи, но вы можете его изменить.

class Post
  def to_param
    "/#{year}/#{month}/#{slug}"
  end
end

(Предполагается, что у вас есть методы в классе Post для года , месяца и slug ).

Теперь, когда URL-адреса сгенерированы, будет вызван ваш замещенный to_param .

<%= link_to @post.title, @post %> 
    => <a href="/2010/02/foobar">Foobar</a>

Очевидно, вы должны убедиться, что действие show PostsController может найти запись на основе переданных параметров.

Возможно, вам придется изменить определение маршрута и исключить этот маршрут:

map.post '/:year/:month/:slug, :controller => :posts, :action => :show

Однако, с переопределением to_param , RESTful post_path по умолчанию будет работать нормально для нужных URL-адресов. чтобы генерировать.

7
ответ дан 4 December 2019 в 13:01
поделиться

К сожалению, когда вы передаете ActiveRecord в link_to , он пытается использовать помощники полиморфных URL-адресов для генерации URL-адреса для ссылки.

Помощники полиморфных URL-адресов предназначены только для создания URL-адресов RESTful с использованием идентификатора записи вашего ActiveRecord.

Поскольку ваш маршрут использует несколько атрибутов объекта Post, помощники Polymorphic URL не оснащены для генерации правильного URL ... не столько ошибка, сколько ограничение :)

Углубление в link_to , когда вы передаете ему хэш, он не использует полиморфную маршрутизацию, поэтому вы избегаете всей проблемы.

Я полагаю, что хакерским подходом было бы определение метода в Post под названием routing_hash , который возвращает

(:year => post.year, :month => post.month, :slug => post.slug)

Я понимаю, что это не СУХОЙ подход, но это лучшее, что я могу придумать на данный момент

3
ответ дан 4 December 2019 в 13:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: