问题
I had problems with forms using polymorphic association for an user sign-up. I want to show fields from multiple models of polymorphic association, but I can't.
Model Classes:
class User < ActiveRecord::Base
devise ...
belongs_to :userable, :polymorphic => true
end
class Advisor < ActiveRecord::Base
has_one :user, :as => :userable
attr_accessible :extra
accepts_nested_attributes_for :user # Idon't know if it is ok
end
class AnotherKingOfUser < ActiveRecord::Base
#the same..
end
I want to make a controller for each specific User type, so:
class AdvisorsController < ApplicationController
# GET /advisors/new
# GET /advisors/new.json
def new
# Here is where I'm not sure about what I did. I tried all variants buy any works for me.
@advisor = Advisor.new
@advisor.build_user
respond_to do |format|
format.html # new.html.erb
format.json { render json: @advisor }
end
end
end
And my view:
<%= form_for(@advisor) do |f| %>
<% if @advisor.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@advisor.errors.count, "error") %> prohibited this advisor from being saved:</h2>
<ul>
<% @advisor.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<% #f.fields_for :user do |ff| %>
<% f.fields_for :user_attributes, @advisor.user||User.new do |ff| %>
<div class="field">
<%= ff.label :email %><br />
<%= ff.text_field :email %>
</div>
<div class="field">
<%= ff.label :password %><br />
<%= ff.text_field :password %>
</div>
<% end %>
<div class="field">
<%= f.label :bio %><br />
<%= f.text_field :bio %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
So in my browser only appears "bio" field, but don't appear extended fields from User model (Devise).
回答1:
class Advisor < ActiveRecord::Base
has_one :user, :as => :userable
attr_accessible :extra, :user_attributes
accepts_nested_attributes_for :user # its ok
end
class AdvisorsController < ApplicationController
def new
@advisor = Advisor.new
# @advisor.build_user # unnecessary
respond_to do |format|
format.html # new.html.erb
format.json { render json: @advisor }
end
end
end
# view
<%= form_for(@advisor) do |f| %>
<%= f.fields_for :user_attributes, @advisor.user||User.new do |ff| %>
<div class="field">
<%= ff.label :email %><br />
<%= ff.text_field :email %>
</div>
<div class="field">
<%= ff.label :password %><br />
<%= ff.text_field :password %>
</div>
<% end %>
...
<% end %>
回答2:
When you're working with association in a form like that (usually with a accepts_nested_attributes_for
like in your case), you need to create objects in order for them to be displayed on the form.
That means that here, when rails builds your form, it looks for the content of @advisor.user
which is empty because I guess that in your controller you did something like
@advisor = Advisor.new
So if you want the fields for the user to appear, you need to build
a user
@advisor = Advisor.new
@advisor.build_user # this will create a instance of User, but will not persist it
With that rails will find the user when building the form, and then displays the field you want.
I hope that answers your question.
来源:https://stackoverflow.com/questions/15455919/form-with-rails-polymorphic-association-for-user-sign-up