考虑一个由各种用户类型组成的应用程序,每个用户类型都有不同的配置文件。在注册期间,允许用户选择他/她的用户类型(即买方或卖方)。
class User < ActiveRecord::Base
belongs_to :profileable, :polymorphic => true
PROFILE_TYPES = %w[Buyer Seller]
end
class Buyer < ActiveRecord::Base
# this is like a buyer profile
has_one :user, :as => :profileable
end
class Seller < ActiveRecord::Base
# this is like a seller profile
has_one :artist, :as => :profileable
end
PROFILE_TYPES
数组在用户控制器的新操作中用于options_for_select
,允许用户选择他/她的用户类型。
视图/用户/ new.html.erb
<%= form_for @user do |f| %>
<%= label_tag "Type" %>
<%= f.select :profileable_type, options_for_select(User::PROFILE_TYPES) %>
<%# ... %>
<% end %>
这样可以正确保存用户的profileable_type
属性。
我的问题是:一旦创建了用户,我希望将它们重定向到Users#show action,其中构建了正确的可分析关联。将根据profileable_type动态呈现表单。
到目前为止,我能够使用以下
呈现正确的表单视图/用户/ show.html.erb
<%= render "#{@user.profileable_type.downcase}/form" %>
然而,这似乎非常不正统,我不太确定如何建立联系。我可以在最初创建用户时创建关联吗?或者我应该在买家#create和卖家#create(上面的表格点)中创建关联?我应该以不同方式对数据建模吗?
通过向用户模型添加attr_accessor :user_type
,我可以正常运行。
app / models / user.rb(已更新)
class User < ActiveRecord::Base
# ...
attr_accessor :user_type
def user_type=(type)
self.profileable = type.constantize.new
self.profileable.save
end
end
views / users / new.html.erb(已更新)
<%= form_for @user do |f| %>
<%= f.label :user_type %>
<%= f.select :user_type, options_for_select(User::PROFILE_TYPES) %>
<%# ... %>
<% end %>
这将创建正确的关联对象,并将profileable_type和profileable_id保存在用户上。然而,这似乎仍然是尴尬和hackish。围绕这个的唯一方法是为每种用户类型分别创建表单吗?这不是很干,因为我没有强迫用户填写他/她选择的配置文件的特定属性,直到创建用户本身。
答案 0 :(得分:0)
@user = @buyer.user.new(params[:user])
@user.save
这将自动保存profileable_type和id。还
<%= render "#{@user.profileable_type.downcase}/form" %>
不是好习惯。你的模型对视图了解得太多了。看起来您应该有买家和卖家表格,而不是用户表格。我需要更多信息来举例。