在我的一个模型中,我有一个名为token
的字段,它是用before_create
创建的。永远不会再修改它。
在routes.rb
我使用它而不是id,如:resources :model, param: :token
所以例如edit
路线现在是model/:token/edit
。
在我的行动中,我正在做find_by(:token, params[:token])
。
我有一个用simple_form
创建的部分表单,正在加载new
和edit
动作。
这很好,路线生成正确,都显示:token:
而不是:id
。
show
行动很好。在展示页面中,我有一个链接到编辑视图的link_to
。这也很好。
两者都在路线中使用:token
,编辑视图加载模型字段,一切正常。
但是,当您查看编辑视图的源代码时,它会将操作显示为/model/<id>
,而不是/model/<token>
。例如/model/5
。
当您提交编辑表单时,它会尝试转到/model/5/
。
此外,当我检查被发送的参数时,它显示token
设置为id
的值。所以,不知何故,token
字段已被重置。
所以
1)token
字段以某种方式被重置为id
的值。我不知道这是怎么回事。
2)simple_form
似乎是基于id
而不是token
产生的行动。但是我已经意识到,因为token
被重置,可能是simple_form
没有做错什么并使用token
的值。
唯一能解决的问题是,手动设置url
中的simple_form_for
字段,但如果我这样做,则会打破new
动作。
对于simple_form
我只是在做:
<%= simple_form_for @model do |f| %>
在routes.rb
我正在做:
resources :model, param: :token
在控制器中,edit
动作是:
@model = Model.find_by(token: params[:token])
update
行动是:
@model = Model.find_by(token: params[:token])
if @mode.update model_params
redirect_to model_path @model.token
else
render 'edit'
end
没有什么花哨的。
在为您生成路由字符串时,simple_form
使用Rails的默认行为。由于config/routes.rb
只为Outside In URL提供了命名模式匹配,因此对于来自内部的应用程序来说它并没有太多意义。对于前者,有这样的路线
model/:token/edit
只是意味着model/
和/edit
之间的任何字符串都将分配给params[:token]
。这并不意味着字符串必须是YourModel#token
的值。当然,您可以通过相同的方式将该模式分配给params[:foobar]
而不会破坏任何东西model/:foobar/edit
要通过id
键完全替换token
键,您必须覆盖方法YourModel#to_param
# app/models/your_model.rb
class YourModel < ActiveRecord::Base
def to_param
token
end
end
因此,ActiveSupport
将知道在从内到外生成路由模式时使用token
作为值。
您可以在Rails's Guides上阅读更多相关信息