带有STI和设计的嵌套表格

时间:2014-09-01 09:20:23

标签: ruby-on-rails devise nested nested-forms sti

关于这个主题的几个问题,但我无法找到解决我的问题的方法。

我有一个名为User的Devise模型(使用单表继承)有一个名为Student的子类(等等)

学生与名为Vehicle的班级有“has_one”关联。

我的模型设置:

class User < ActiveRecord::Base
    devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable
end

class Student < User
    has_one :vehicle, :dependent => :destroy
    accepts_nested_attributes_for :vehicle, allow_destroy: true
end

class Vehicle < ActiveRecord::Base
    belongs_to :student
end

我想创建一个嵌套表单,其中包含用户字段,学生字段,然后是车辆字段,例如:

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>

*** User fields***

    <% if @class == "Student" %>

    *** Student fields***

        <% f.fields_for :vehicle do |builder| %>

             *** Vehicle fields***

            <%= f.hidden_field :_destroy %>
            <%= link_to "remove", '#', class: "remove_fields" %>

        <% end %>

        <%= link_to_add_fields "Add vehicle", f, :vehicle %>

     <% end %>
<% end %>

问题是我在User对象上遇到了一个未定义的方法错误:vehicle。这并不奇怪,因为我在模型中实际上没有将车辆与用户相关联。我只是不确定该怎么做。

我的用户/注册控制器具有以下注册方法:

# GET /users/sign_up

    def new
        @class = params[:class]

        build_resource({})
        respond_with self.resource
    end

给定了为User类设置的设计,我认为这会创建一个'user'类型的资源并将其传递给我的视图,然后该视图无法将其链接到'Vehicle'。

有没有办法创建所需的关联或创建“student”类型的资源以传递给视图?

1 个答案:

答案 0 :(得分:1)

这可能不是答案(如果需要,我会删除),但我会给你我的观察和答案。思路:

-

创建

您目前正在使用users#sign_up作为控制器方法,但是您希望填充Student类?

我不知道Devise将如何在这种性质下工作,但我知道如果你想正确使用STI,你最好使用直接使用本机对象。例如,如果您希望创建学生,您最好使用以下内容:

#app/controllers/students_controller.rb
class StudentsController < InheritedResources::Base #-> assuming you wish to use Inherited Resources

   def new
      new!(@student.build_vehicle)
   end

   private

   def permitted_params
      params.permit(:student => :your, :student, :params, vehicle_attributes: [:vehicle, :attributes])
   end    
end 

这将使您能够使用与您使用的相同的表单,除了它只显示student记录:

#app/views/students/new.html.erb
<%= form_for resource, as: resource_name do |f| %>
   <% if resource_class == "Student" %>
       ...
   <% end %>
<% end %>

这将允许您创建一个新的Student对象(之前您还没有)

我不知道这可以与Devise一起使用,但我确信如果您按照上面的描述发送请求,那么您将能够创建一个Student对象,因此,能够创建您需要的功能