【问题标题】:Devise with Associated Record validation设计相关记录验证
【发布时间】:2012-08-29 18:30:37
【问题描述】:

我的背景

am/是一名 PHP 开发人员。已经15年了。 Ruby 对我来说是新的(我的新挑战)!

当前设置

我正在使用带有用户模型的设计。
导轨:3.2.1
设计:2.1.2

用例

当用户注册时(通过 Devise 控制器),我想创建用户记录,但也自动创建一个 Foo 记录。我创建了一个 after_create 来处理 Foo 记录的创建。

Class User < ActiveRecord::Base

  after_create :make_foo

  def make_foo
    Foo.create(
      :name => name,
      :user_id => id
    )
  end

end

Class Foo < ActiveRecord::Base

    belongs_to :user

end

症状

我遇到了一个问题,当没有创建 Foo 记录(例如验证)时,仍然创建了 User 记录(我不希望这样)。我在 after_create 中添加了一个引发异常,它会回滚用户创建。
但是,我更喜欢一些好的错误处理而不是抛出异常。现在我得到一个带有该异常的 500 错误页面。 我希望表单可以再次显示失败的原因。

Class User < ActiveRecord::Base

  after_create :make_foo

  def make_foo
    foo = Foo.create(
      :name => name,
      :user_id => id
    )
    if !foo.valid?
      raise Exception.new('Foo creation failed.')
    end
  end

end

请求帮助

有什么建议吗?

【问题讨论】:

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


    【解决方案1】:

    您可以通过在

    中设置 flash 消息重定向回同一页面,而不是引发异常
      if !foo.valid?
    

    这样屏蔽

     flash[:error] = 'error msg'
    

    并使用

    重定向
     session[:return_to] = request.referer
     redirect_to session[:return_to]
    

    【讨论】:

    • 感谢您抽出宝贵时间回答。也许不清楚,但创建 Foo 记录的代码不在控制器中,而是在模型中。将 Session 和重定向以及 flash 逻辑放在模型中是不好的。它通常进入控制器内部。控制器不是我的,而是 Devise 的控制器。我希望这有助于澄清我的情况。
    【解决方案2】:

    我最终覆盖了 Devise Resitrations Controller 并在 create 方法中放置了 begin...rescue...end。

    # routes.rb
    devise_for :users, :controllers => { :registrations => "my_devise/registrations" }
    
    # app/controllers/my_devise/registrations_controller.rb
    class MyDevise::RegistrationsController < Devise::RegistrationsController
      def create
        begin
          super
        rescue Exception
          self.resource.errors[:base] << "My error message here"
          clean_up_passwords resource
          respond_with resource
        end
      end
     end
    

    【讨论】:

      【解决方案3】:

      您可能想查看Rails3: Devise User has_one relationship,看看更好的建模是否可以让问题变得更容易。

      您现在对 user.rb 建模的方式确实是这样的,即用户 可能 没有 Foo 存在(但是 必须 属于用户),所以它只是调用 :make_foo 作为 after_create 回调,没有任何其他保证。

      【讨论】:

      • 看起来很有希望。然而,就我而言,我的 Foo(Team) 是多态的,因为 Foo 可以属于用户记录以外的其他内容。这意味着我不确定这是否适用于我的情况,但我会看看。谢谢,
      猜你喜欢
      • 1970-01-01
      • 2011-07-09
      • 1970-01-01
      • 2014-09-18
      • 1970-01-01
      • 1970-01-01
      • 2021-05-13
      • 1970-01-01
      • 2011-11-28
      相关资源
      最近更新 更多