2014-01-14 3 views
0

У меня есть два разных типа пользователей в моем приложении, которые используют Devise для аутентификации с использованием Rails 4, но у них очень разные поля. Один - Покупатель, а другой - Продавец. Покупатель должен иметь информацию о местоположении и платежах, пока Продавец не делает этого. Первоначально я думал, что было бы неплохо создать две отдельные модели Devise, но должен быть лучший способ. Я думал о том, чтобы хранить все в одной таблице и сериализовать данные оплаты Покупателя.Две очень разные модели пользователей в Devise

Что было бы хорошим решением?

+0

В чем причина вы не делаете для различных моделей? Они наверняка представляют собой разные объекты. –

+0

Много проблем возникает, когда у вас есть две модели Devise, видимо, – user3193550

+0

. Вы получите помощники для каждой модели, например current_seller и current_buyer. Но, поскольку вам все равно нужно их отделить, я думаю, это облегчит вам жизнь. Я делаю это с пользователями и admin_users. Если вы ненавидите идею двух моделей, взгляните на [cancan] (https://github.com/ryanb/cancan). Это дает вам возможность предоставлять роли пользователям, но не предназначен для использования вами. –

ответ

0

Посмотрите на ИППП - короче создать одну базовую модель под названием User, а затем два подкласса User::Buyer и User::Seller (Нет необходимости для пространства имен, но рекомендуется). Обе модели хранятся в одной таблице, и все, что применяется к модели User, повлияет на оба этих класса. Подробнее об ИПППАХ here

UPDATE:

Если вы не хотите иметь количество пустых ячеек таблицы, вы можете использовать 1-1 ассоциацию, чтобы сохранить все детали классовых. Вы можете также добавить оболочку, чтобы полностью ее инкапсулировать. Это может выглядеть следующим образом:

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 

Вы можете смешать его с ИППП:

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 

Тогда вы можете просто работа с помощью:

user = User::Buyer.new 
user.buyer_attribute  #=> nil 
user.seller_attribute  #=> NoMethod error! 

Примечание: Вы должны иметь details_type string на вашей модели User, а также details_id для работы с полиморфной ассоциацией. Для ИППП вам понадобится другая колонка type.

+0

Будет ли STI хорошо работать, если единственными полями, на которых они действительно имеют общие имена, являются имена, адрес электронной почты и пароль? – user3193550

+0

Я обновил ответ на разделение этих атрибутов моделей. – BroiSatse

0

Честно говоря, вместо этого я использую полиморфные отношения. Я сохраняю модель User в значительной степени для аутентификации, а затем создаю две новые модели (Покупатель и Продавец) с полями, которые они не разделяют. Это очень близко к методу BroiSate, показанному выше.

Пример

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 
Смежные вопросы