J'aime beaucoup la réponse d'Adam Tanner, mais je la définirais un peu différemment. Tout d'abord, la façon dont une organisation s'associe aux administrateurs ne fonctionne pas comme décrit: vous devez avoir une clé étrangère différente dans votre table utilisateur, et spécifier cela dans l'association has_one :admin
. Mais je ne pense pas que ce soit un bon chemin de toute façon, car il vous limite à un administrateur par organisation, et limite un utilisateur appartenant à une organisation.
Ma version est un peu plus compliquée, mais je pense que ça se passe bien. Premièrement, admin doit être un rôle qu'un utilisateur a ou n'a pas avec une organisation. Je traiterai d'abord le problème utilisateur/org, et enregistrerai le problème d'adresse pour plus tard.
Voici les migrations, que vous pouvez améliorer avec ce que d'autres domaines dont ils ont besoin:
create_table :organizations do |t|
# your fields go here
end
create_table :users do |t|
# your fields go here
end
create_table :memberships do |t|
t.integer :user_id
t.integer :organization_id
t.boolean :is_admin
end
add_index :memberships, [:user_id, :organization_id]
Comme vous pouvez le voir, nous ajoutons une table d'adhésions, qui va connecter les utilisateurs et les organisations. Nous ajoutons également un index pour accélérer un peu l'association. Maintenant pour les modèles:
class Organization < ActiveRecord::Base
has_many :memberships
has_many :users, :through => :memberships
end
class User < ActiveRecord::Base
has_many :memberships
has_many :organizations, :through => :memberships
def membership_in organization
self.memberships.detect{|m| m.organization = organization}
end
def is_admin_for? organization
self.membership_in(organization).is_admin?
end
def set_admin_for organization, value
self.membership_in(organization).update_attribute(:is_admin, value)
end
end
class Membership < ActiveRecord::Base
belongs_to :organization
belongs_to :user
end
Ici, nous connectons nos utilisateurs et organisations par le biais des adhésions. Un utilisateur peut être un administrateur pour l'une des organisations auxquelles il appartient. J'ai créé quelques méthodes pour définir et obtenir le statut d'administrateur d'un utilisateur dans une organisation, dans le modèle d'utilisateur.
Suivant les adresses: Je l'ai déjà abordé celui-ci dans un billet de blog de la mine:
http://kconrails.com/2010/10/19/common-addresses-using-polymorphism-and-nested-attributes-in-rails/
Si vous avez des questions, s'il vous plaît demander. Bonne chance!
MISE À JOUR
Edward M. Smith a souligné dans les commentaires que mes méthodes d'administration ne sont pas très tolérant aux pannes.J'essayais de garder le code aussi propre que possible pour l'exemple, mais il a un point. Voici donc la version plus musclée que les comptes pour avoir tenté d'utiliser une appartenance à une organisation que l'utilisateur ne partie de:
def is_admin_for? organization
membership = self.membership_in(organization)
return false if membership.nil?
membership.is_admin?
end
def set_admin_for organization, value
membership = self.membership_in(organization)
return false if membership.nil?
membership.update_attribute(:is_admin, value)
end
Comme toujours, le développement piloté par les tests est le meilleur, mais je n'ont généralement pas le temps de le faire pour les questions stackoverflow :)
Question d'un rail/ruby noob. 'membership_in' retourne nil ou l'instance d'organisation, n'est-ce pas? Que se passe-t-il sur un is_admin_for? appeler où l'utilisateur n'est pas dans l'organisation? N'est-ce pas appeler is_admin? sur zéro, et donc une erreur? –
Très vrai, c'est beaucoup de code que j'ai tapé pour une réponse stackoverflow, donc je n'ai pas construit beaucoup de tolérance de panne, ou utiliser TDD comme je le ferais pour le code de travail :) Bonne prise, et je corrigerai il. –
Oh, je ne critiquais pas. Je suis encore en train de travailler sur la compréhension de Ruby (j'ai dû chercher la méthode 'detect' sur les collections, par exemple) donc je voulais savoir si j'avais bien compris les choses. :) –