我正在使用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)
为什么不可能?我想当我构建关联模型时,设计不会保存对资源的更改。我看到的唯一出路是定义我自己的变量,其中包含更新资源的完整副本。不过,这不是一个好习惯。
你会做什么?
答案 0 :(得分:1)
我认为问题在于默认RegistrationsController.new
只是:
def new
build_resource({})
respond_with self.resource
end
(这取决于你的设计版本,但在相当长的时间内似乎是这个或相当的。)
这意味着在您覆盖的respond_with
中添加嵌套模型之前,视图会呈现(new
),因为您在调用super
后执行此操作。我认为你有两个选择:
super
。只需将new
的第一行放在new
的开头,将最后一行放在默认new
的最后一行。build_resource
而不是new
。在被覆盖的build_resource
开始时,请致电super
,然后在new
super
之后添加build_resource
中的代码。您需要做的唯一额外事情是检查build_resource
是使用nil
调用还是空哈希,在这种情况下,您构建空白user_info等,或者是否使用非调用-empty hash然后不添加你的空白user_info等,因为build_resource
必须是从create
调用的,所以哈希将包含你的用户在表单上为user_info输入的内容,所以你不要我想用空白版本覆盖! (你也许可以查看当前的url或类似的东西,而不是检查hash参数,但我个人更喜欢那样。)我过去曾使用过选项2。我喜欢它,因为它仍然调用super
,所以我们仍然使用设计build_resource
的实现,而选项1完全忽略了设计new
的实现 - 如果它们使一些重要将来你改为他们的new
你会错过吗? (例如,曾经有一个resource
变量位于new
的本地变量,但它现在位于self
,正如您在上面的代码中所看到的那样。)选项2只是更加繁琐因为您需要检查是否应该添加空白的user_info等。所以这取决于您的口味!