【问题标题】:Rails 3: Custom Restful Routes: Change Edit-Action behaviorRails 3:自定义 Restful Routes:更改 Edit-Action 行为
【发布时间】:2012-02-24 17:40:43
【问题描述】:

对于我的项目,我需要自定义 url,这些 url 应该不容易猜到,因为它是随着对象的整数 id 的增加而增加的。为了解决这个问题,我给我的对象一个 unique_id 属性,它是一个字符串,并编写了 resources :objects 自己生成的七个动作,如下所示:

  get '/objects' => 'objects#index', as: :objects 
  post '/objects' => 'objects#create'
  get '/objects/new' => 'objects#new', as: :new_object
  get '/:unique_id/edit' => 'objects#edit', as: :edit_object
  get '/:unique_id' => 'objects#show', as: :object
  put '/:unique_id' => 'objects#update'
  delete '/:unique_id' => 'objects#destroy'

一切都很好,我只需要告诉控制器通过Object.find_by_unique_id(params[:unique_id])而不是Object.find(params[:id])找到对象 我可以完美地创建、阅读和删除,但我无法更新。

当我打开 edit_object_path 时,它会正确呈现表单,但是当我单击“更新对象”时,它会搞砸。 从 WEBrick 输出我可以看到它创建了一个 PUT 请求,但它请求对象的 id 而不是 unique_id。例如,不是请求PUT /osefushe7398hr9,而是声明PUT /26。 update 方法甚至没有被调用,而是要求创建一个 unique_id 为 26 的新对象。

我真的不知道在哪里更改该行为或如何传递 unique_id 而不是 id。

【问题讨论】:

  • 你是否更改了form_for的url?,我认为这是问题所在。尝试 form_for @object, url => {update_object_path(@object.unique_id)} 并编辑要放置的更新路线 '/:unique_id' => 'objects#update', :as => :update_object
  • 另外,看看这个截屏视频railscasts.com/episodes/…

标签: ruby-on-rails rest routing


【解决方案1】:

Rails 模型有一个您可能需要重写的方法来完成此操作,称为to_param 方法。此方法的默认行为是返回模型实例的 ID(我相信您正在尝试更改)。

使用您当前的布局,我会放弃您所有的路线更改。在模型中,添加:

def to_param
  "#{unique_id.parameterize}"
end

所以现在,通过正常路由,/objects/:variable 的请求将按照您的意愿行事。

使用 parameterize 方法,您不会遇到不友好的 URL。

重写 to_param 方法的一个小缺点是,现在在控制器中使用 Model.find 方法的其他操作(:edit、:update 和 :destroy)都需要更改为 Model.find_by_unique_id [如果你保持 RESTful]。

【讨论】:

  • 这实际上不会阻止通过它们的 object/:id 路径访问对象
【解决方案2】:

在一个表单中,您可以明确地告诉它要发布到哪个 URL 以及要与之一起使用的参数。例如(使用 HAML 和 form_tag)

= form_tag object_path(@object.unique_id), :method => :put do

您还可以更明确地使用:

= form_tag object_path(:id => @object.unique_id), :method => :put do

【讨论】:

  • 这很奇怪,当我使用此方法并单击更新时,它似乎采用了原始的 unique_id(而不是以前的 id),但将其转换为小写。然后试图找到一个不存在的unique_id为小写字母的对象,并再次想创建一个unique_id为小写字母的新对象...
【解决方案3】:

好的解决方案是添加

def to_param
  unique_id
end

到没有参数化或 #{} 语法的对象模型。 实际上,我在尝试将 unique_id 传递给第二个解决方案中提到的表单时发现了这一点。事实证明,我不必像解决方案二中建议的那样更改 form_for 标记。参数化是为什么将 unique_id 设为小写的原因。

现在一切都按预期进行(并且仍然很安静)

【讨论】:

    猜你喜欢
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多