【问题标题】:Rails Devise Build nested model in controllerRails Devise 在控制器中构建嵌套模型
【发布时间】:2014-02-13 21:06:17
【问题描述】:

我正在使用Devise 并尝试在我的RegistrationsController 中构建嵌套模型。

虽然这不起作用。我可以通过

构建嵌套模型
resource.build_nested_model

在视图中,但不在控制器本身中。

这是我的registrationscontrollers 的新动作

  def new
    super
    resource.build_user_info
    resource.user_info.languageskills.build
    if params[:is_driver].to_i == 1
      resource.build_driver
    end
    Rails.logger.debug(resource.build_user_info.inspect)
  end

这是它生成的输出

Started GET "/en/sign_up?is_driver=1" for 127.0.0.1 at 2014-02-13 13:20:01 +0100
Processing by RegistrationsController#new as JS
  Parameters: {"is_driver"=>"1", "locale"=>"en"}
  Rendered registrations/_new_user_fields.html.erb (12.1ms)
  Rendered registrations/new.html.erb within layouts/application (27.8ms)
  Rendered layouts/_header.html.erb (2.8ms)
  Rendered layouts/_messages.html.erb (0.2ms)
  Rendered layouts/_footer.html.erb (0.6ms)
   (0.2ms)  begin transaction
   (0.1ms)  commit transaction
#<UserInfo id: nil, user_id: nil, first_name: nil, last_name: nil, year_of_birth: nil, city: nil, created_at: nil, updated_at: nil, gender_id: nil, interests: nil, about: nil, country_alpha2: nil>
Completed 200 OK in 117ms (Views: 96.5ms | ActiveRecord: 0.4ms)

为什么不可能?当我构建相关模型时,我猜想设计并没有保存我对资源的更改。我看到的唯一出路是定义我自己的变量来保存更新资源的完整副本。不过,这不是一个好习惯。

你会怎么做?

【问题讨论】:

    标签: ruby-on-rails devise controller


    【解决方案1】:

    我认为问题在于默认的RegistrationsController.new 只是:

    def new
      build_resource({})
      respond_with self.resource
    end
    

    (这取决于您的设计版本,但在很长一段时间内似乎是这个或等效的。)

    这意味着在您将嵌套模型添加到覆盖的new 之前(由respond_with)渲染视图,因为您在调用super 之后执行此操作。我认为你有两个选择:

    1. 请勿致电super。只需将默认new 的第一行放在new 的开头,将默认new 的最后一行放在你的末尾即可。
    2. 覆盖build_resource 而不是new。在覆盖的build_resource 的开头,调用super,然后在build_resource 中的super 之后添加new 中的代码。您需要做的唯一额外的事情是检查 build_resource 是使用 nil 还是空哈希调用的,在这种情况下,您将构建空白 user_info 等,或者如果使用非空哈希调用它不要添加您的空白 user_info 等,因为必须从 create 调用 build_resource,因此哈希将包含您的用户在 user_info 表单中输入的任何内容,因此您不想用空白版本覆盖! (您也许可以检查当前 url 或类似的东西,而不是检查哈希参数,但我个人不喜欢这样。)

    我过去曾使用过选项 2。我喜欢它,因为它仍然调用super,所以我们仍然使用设计对build_resource 的实现,而选项1 完全忽略设计对new 的实现——如果他们对其new 进行一些重要更改怎么办将来你会错过什么? (例如,以前有一个new 的局部变量resource,但现在它位于self 上,如您在上面的代码中所见。)选项2 稍微复杂一点,因为您需要检查是否你应该添加你的空白 user_info 等。所以这取决于你的口味!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-28
      • 2014-04-03
      • 1970-01-01
      • 1970-01-01
      • 2012-03-29
      • 1970-01-01
      • 2021-12-07
      相关资源
      最近更新 更多