问题
I have two different types of users in my application that uses Devise for authentication using Rails 4 but they have very different fields. One is a Buyer and the other is a Seller. The Buyer must have location and payment information while the Seller doesn't. Initially I thought it would be a good idea to create two separate Devise models but there has to be a better way. I thought about keeping it all in the same table and serializing the Buyer's payment data.
What would be a good solution?
回答1:
Have a look at STI - in short you create one base model called User
and then two subclasses User::Buyer
and User::Seller
(No need for namespacing, but it is recommended). Both models are stored in same table and everything applied to User
model will affect both those classes. More about STI here
UPDATE:
If you don't want to have a number of empty table cells, you might use 1-1 association to keep all class-specific details. You can also add a wrapper to encapsulate it completely. It could look like this:
class User < ActiveRecord::Base
belongs_to :details, polymorphic: true
def method_missing(method, *args)
return details.send(method, *args) if details.respond_to? method
super
end
end
class BuyerDetails < ActiveRecord::Base
has_one :user, as: :details
# buyer_attribute column
end
class SellerDetails < ActiveRecord::Base
has_one :user, as: details
#seller_attribute
end
You can then mix it with STI:
class User::Buyer < User
def initialize(*args)
super
details = BuyerDetails.new
end
end
class User::Seller < User
def initialize(*args)
super
details = SelerDetails.new
end
end
Then you can simple work using:
user = User::Buyer.new
user.buyer_attribute #=> nil
user.seller_attribute #=> NoMethod error!
Note: You will need to have details_type
string column on your User
model as well as details_id
for polymorphic association to work. For STI, you will need another column type
.
回答2:
Honestly I use polymorphic relations instead. I keep my User model pretty much for authentication, then make two new models (Buyer and Seller) with the fields they don't share in common. This is very close to BroiSate's method shown above.
Example
class User < ActiveRecord::Base
belongs_to :authenticatable, polymorphic: true
end
class Buyer < ActiveRecord::Base
has_one :user, as: :authenticatable
# Add buyer specific fields to this table
end
class Seller < ActiveRecord::Base
has_one :user, as: :authenticatable
# Add seller specific fields to this table
end
来源:https://stackoverflow.com/questions/21110984/two-very-different-user-models-in-devise