在Rails 3.2中使用find_or_initialize_by时,如何尊重RESTful方法?

时间:2012-03-29 03:48:07

标签: ruby-on-rails ruby ruby-on-rails-3 rest activerecord

我的项目中有一个资源可以从用户那里收集一些信息。基本上,这是他们在访问网站的另一个区域之前填写的表格。然后它会设置一个星期的cookie,但是如果他们回来,它会查找他们之前的条目,并保持他们的偏好与他们相关(并且只要电子邮件地址匹配,就会更新任何细节)。

目前,我有一个申请人控制器,如下所示:

class ApplicantsController < ApplicationController

  ...

  def create
    @applicant = Applicant.find_or_initialize_by_email(params[:applicant])
    if @applicant.new_record? ? @applicant.save : @applicant.update_attributes(params[:applicant])
      set_cookie_and_redirect
    else
      render 'new'
    end
  end

  def update
    if @applicant.update_attributes(params[:applicant])
      set_cookie_and_redirect
    else
      render 'new'
    end
  end

end

set_cookie_and_redirect是一个私有方法,它只设置一些cookie并将用户重定向到页面。代码有效,但只是感觉很脏。它本质上是在创建方法中更新记录,条件是它不是新记录。我还被迫有一个更新方法,以防现有记录带回验证错误 - 表单助手然后将表单切换到发送到更新方法。

所以对我来说...是否有更合适的方法将create方法中的update_attributes调用推送到更新方法?或者更好的说,是否有更好的方法来尊重RESTful方法来隔离创建和更新功能?

更新:我想要更具体一点。如果用户填写此表单之前会设置一个cookie,这样他们就不必再填写七天了。但是,七天后,cookie已过期,他们再次看到该表单。在将用户输入添加到表单中之前,控制器不知道用户是新用户还是现有用户,然后根据电子邮件地址进行比较。

提前致谢!我非常期待任何人对此的看法。

1 个答案:

答案 0 :(得分:0)

create方法只应创建,而update方法只应更新。让Rails根据呈现表单时@applicant内部的内容决定将要发生的事情 - 它基本上就是你正在做的事情:检查记录是否是新记录,并将其发送给{{1相应地} / update。例如:

create

Rails会根据申请人对象的def applicant @applicant = Applicant.find_or_initialize_by_email(cookies[:email]) # renders applicant.html.erb form end <%= form_for @applicant do |f| %> # ... fields ... <% end %> def create @applicant = Applicant.new(params[:applicant]) @applicant.save # .. etc. end def update @applicant = Applicant.find_by_email(cookies[:email]) @applicant.update_attributes(params[:applicant]) # ... etc. end 状态将请求发送到正确的操作。