2009-09-26 13 views
9

Estoy un poco confundido acerca de cómo funciona esto, incluso si funciona correctamente. Tengo un modelo que tiene dos asociaciones con el mismo otro modelo.has_one y has_many en el mismo modelo. ¿Cómo los raíles los rastrean?

La empresa tiene un propietario y la empresa tiene muchos empleados de los usuarios de la clase.

aquí es mi modelo de empresa:

class Company < ActiveRecord::Base 
    validates_presence_of :name 

    has_many :employee, :class_name => 'User' 
    has_one :owner, :class_name => 'User' 
    accepts_nested_attributes_for :owner, :allow_destroy => true 
end 

aquí es mi modelo de usuario:

class User < ActiveRecord::Base 
    include Clearance::User 
    attr_accessible :lastname, :firstname #other attr are whitelisted in clearance gem 
    validates_presence_of :lastname, :firstname 
    belongs_to :company 
end 

Ahora suponiendo que tengo 3 empleados de esta compañía, incluyendo el propietario. Cuando creo por primera vez la empresa, configuro el propietario para el empleado con id 1 y los otros dos (2,3) se agregan a la lista de empleados al establecer su company_id (user.company = company). Los tres tienen su id_compañía establecida en el id. De la compañía, que podemos suponer que es 1

cuando solicito company.owner, obtengo el usuario correcto y cuando hago compañía. Empleado, obtengo los tres.

Si cambio el propietario al usuario 2, el usuario 1 se elimina automáticamente de los empleados al establecer su company_id en cero. Esto está bien y si lo vuelvo a agregar como un simple empleado, todo sigue siendo bueno.

¿Cómo sabe el rayo cuál es cuál? Lo que quiero decir es ¿cómo sabe que un empleado es dueño y no solo un empleado? Nada en el esquema define esto.

Tengo la sensación de que debería invertir la asociación de propietarios y hacer que la empresa pertenezca a un usuario.

Respuesta

12

Como lo tiene ahora, no hay nada que distinga a los propietarios de los empleados. Lo que significa que se encontrará con problemas una vez que comience a eliminar personas o intente cambiar la propiedad.

Como señala François, solo estás teniendo suerte porque el propietario es el usuario que pertenece a la empresa con el ID más bajo.

Para solucionar el problema, mis modelos se relacionan en la siguiente herramienta.

class Company < ActiveRecord::Base 
    belongs_to :owner, :class_name => "user" 
    has_many :employees, :class_name => "user" 
    validates_presence_of :name 
    accepts_nested_attributes_for :owner, :allow_destroy => true 
end 

class User < ActiveRecord::Base 
    include Clearance::User 
    attr_accessible :lastname, :firstname #other attr are whitelisted in clearance gem 
    validates_presence_of :lastname, :firstname 
    belongs_to :company 
    has_one :company, :foreign_key => :owner_id 
end 

Deberá agregar otra columna llamada owner_id a la tabla Companies, pero esto define más claramente sus relaciones. Y evitará cualquier problema asociado con el cambio de propietario. Tenga en cuenta que puede haber una dependencia cíclica si realiza esta ruta y establece su base de datos para que ambos usuarios.company_id y companies.owner_id no pueden ser nulos.

No estoy seguro de qué tan bien accept_nested_attributes_for jugará con una relación belongs_to.

+0

Terminé haciendo esto y en el lado del usuario, hice belongs_to: employer,: class_name => "Company", que tenía que hacer para evitar un conflicto con user.company, ahora user.company es la empresa y la empresa de su propiedad .employer es ... entiendes el punto: P – nkassis

0

Usted podría tener un modelo llamado la propiedad -

ownership belongs_to company 
ownership belongs_to user 

user has_many ownerships 
company has_one ownership 
5

has_one es el azúcar sintáctica para:

has_many :whatevers, :limit => 1 

tiene uno añade el bit :limit => 1, asegurando de esta manera solamente 1 registro se devuelve nunca. En su tiene una declaración, asegúrese de tener una cláusula :order, para devolver el registro correcto en todas las circunstancias. En este caso, pondría una bandera en el empleado para indicar quién es el propietario, y ordenaré por esta columna para obtener el registro correcto primero.

Su pregunta sobre cómo Rails lo sabe es porque la mayoría de las bases de datos devolverán registros en su orden de clave principal. Entonces, el primer empleado agregado tiene ID 1, por lo tanto será devuelto primero.

Cuestiones relacionadas