Reputation: 873
Quite a few questions on this topic, but I can't find a solution to my issue.
I have a Devise model called User which (using Single table inheritance) has a subclass called Student (among others)
Student has a 'has_one' association with a class called Vehicle.
My model set up:
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
I want to create a nested form which has the User fields, Student fields, and then the vehicle fields, i.e. something like this:
<%= 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 %>
The issue is that I get an undefined method error for :vehicle on a User object. This is not surprising given that I haven't actually related Vehicles to Users in my models. I'm just not sure how to do it.
My users/registrations controller has the following sign-up method:
# GET /users/sign_up
def new
@class = params[:class]
build_resource({})
respond_with self.resource
end
Given devise is set up for the User class, I think this creating a resource of type 'user' and passing it through to my view, which then can't link it to a 'Vehicle'.
Is there any way to create the required associations or to create a resource of type 'student' to pass through to the view?
Upvotes: 1
Views: 277
Reputation: 76774
This might not be an answer (I'll delete if required), but I'll give you my observations & ideas:
--
Create
You're currently using users#sign_up
as the controller method, yet you wish to populate the Student
class?
I don't know how Devise will work in this nature, but I do know that if you want to use STI's correctly, you'll be best using the native objects directly. For example, if you wish to create a student, you'll be best using the following:
#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
This will give you the ability to use the same form as you were using, except it will only show the student
records:
#app/views/students/new.html.erb
<%= form_for resource, as: resource_name do |f| %>
<% if resource_class == "Student" %>
...
<% end %>
<% end %>
This will allow you to create a new Student
object (which you weren't before)
I don't know this will work with Devise, but I know for sure that if you send the request as I have outlined above, you'll be able to create a Student
object, and consequently, be able to create the functionality you need
Upvotes: 1