Ruby on rails 如果我想覆盖资源路径(例如post_path(@post)),我应该在哪里做?

Ruby on rails 如果我想覆盖资源路径(例如post_path(@post)),我应该在哪里做?,ruby-on-rails,ruby,Ruby On Rails,Ruby,更新(再次)|忽略我之前在这里设置的模块thing-o。最好只使用来设置参数并使路由正常工作 to_param if slug "#{id}-#{slug}" else super end end match "/posts/:id(-:slug)" => "posts#show", :as => :post, :constraints => { :id => /\d+|\d+-.*/ } 诀窍就在这条路上。它使-:slug成为可选,并向:

更新(再次)|忽略我之前在这里设置的模块thing-o。最好只使用
来设置参数
并使路由正常工作

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
),但管道允许它也匹配一个后跟slug的数值,以便生成路由。这是一个温和的黑客行为,但整个事情真的是。允许资源提供参数散列可以解决这个问题。这可以应用于您想要的任何奇特路线(例如,将
:id
放在末尾而不是起点)

Rails 3.0.7

采取如下路线:

match "/posts/:id-:slug" => "posts#show", :as => :post
这为我提供了一个
post_path(obj)
helper,但当然,它只想从我的模型中生成一个参数,从我所知道的情况来看,没有办法从我的模型的
返回多个值到_param
方法。我知道我可以这样写
到_param

to_param
  "#{id}-#{slug}"
end
但这是作为单个参数传递给route的,route最终不匹配任何routes。类似地,我知道我可以从我的路线中删除
“-:slug”
,但是
:id
参数包含虚假输入,基本上是一种黑客行为(尽管显然已经完成了)

如果Rails的未来版本允许您将散列从
返回到\u param
,那将是非常棒的,比如:

to_param
  { :id => id, :slug => slug }
end
然后在找到正确的路线时使用这些

我想弄清楚的是,我应该在哪里重写
post\u path()
,以提供正确的路由。我可以把它放在视图帮助器中,但是在我的控制器中它不可用,所以我猜这是一个错误的地方


只是好奇胜过一切。我知道如果我在路由上省略
:slug
,效果很好,但是在更复杂的情况下,我可以想象覆盖默认路径是一件有用的事情。通过传递一个资源就可以生成一条路线,这是我想采用的一个非常好的特性,但是市场部总是让我们在URL中填充各种关键字,因此一些控制将是非常好的:)

路由有两个方面:路由生成和路由匹配

正如您所指出的,路由生成非常简单。在任何ActiveModel中,将
覆盖到_param

# In a model:
def to_param
  # Use another column instead of the primary key 'id':
  awesome_identifier.to_s
end
路径匹配不太明显。可以指定
:awesome\u标识符
,以代替默认资源路由中每次出现的
:id
。但是,我发现,如果您将
:id
留在路线中,并且只更改控制器中的逻辑,Rails将给您更少的阻力。请注意,这是一种权衡,因为从根本上讲,路线中的
:id
并不正确

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

正如您所注意到的,Rails优化了单个用例:如果您希望主键用于快速记录查找,但仍然希望在URL中包含一个slug,以便于用户友好或搜索引擎优化。在这种情况下,您可以从
to_param
方法返回一个字符串,格式为
“#{id}-#{whatever}”
,将相同字符串返回
find
方法时,破折号后面的所有内容都将被忽略。

谢谢。您知道Rails在哪里查找
post\u path()
方法吗?在控制器中重写它意味着它对视图不可用。在帮助器中重写它意味着控制器无法使用它。我正在考虑制作一个模块,并将其包含在助手和控制器中。我知道我真的应该只使用:id,尽管它不正确,但它会在我的脑海中反复思考,什么是避免它的最干净的方法;)这是可行的,尽管我不完全确定这是“最好”的方式。创建一个名为
custompath
的模块,然后在
ApplicationController
中包含该模块,并在
ApplicationHelper
中包含该模块以使其可供视图使用。现在,
link\u到
,朋友们将首先在这里看到任何
*\u路径
方法。我真的认为你不应该尝试覆盖URL帮助器方法。实现不同的
to_param
方法要容易得多,这将满足您的需要。路线匹配部分更难完成。我认为你是对的。您可以使用以下路由进行一些欺骗:
“/posts/:id(-:slug)”…:约束=>{:id=>/\d+\d+-.*/}
。这有点诡计多端,但基本上它意味着可以使用
:id=>“123 slug here”
生成路由,但当请求传入时,它被分为
:id
:slug
参数。