Rails: Cómo limitar el número de elementos en la asociación has_many (de Parent)
Me gustaría limitar el número de elementos en una asociación. Quiero asegurarme de que el usuario no tenga más de X Things. Esta preguntase preguntó antes y la solución tenía la lógica en el niño:
La solución ofrecida (para un problema similar):class User < ActiveRecord::Base
has_many :things, :dependent => :destroy
end
class Thing <ActiveRecord::Base
belongs_to :user
validate :thing_count_within_limit, :on => :create
def thing_count_within_limit
if self.user.things(:reload).count >= 5
errors.add(:base, "Exceeded thing limit")
end
end
end
El "5" codificado es un problema. Mi límite cambia según el padre. La colección de cosas conoce su límite en relación con un usuario. En nuestro caso, un Gerente puede ajustar el límite (de Cosas) para cada Usuario, por lo que el Usuario debe limitar su colección de Cosas. Nosotrospodrí have thing_count_within_limit solicita el límite de su usuario:
if self.user.things(:reload).count >= self.user.thing_limit
Pero, eso es muchousuari introspección de Thing. Múltiples llamadas al usuario y, especialmente, que(:reload)
son banderas rojas para mí.
Penséhas_many :things, :before_add => :limit_things
funcionaría, pero debemos plantear una excepción a detener la cadena. Eso me obliga a actualizar things_controller para manejar excepciones en lugar de la convención de rails deif valid?
oif save
.
class User
has_many :things, :before_add => limit_things
private
def limit_things
if things.size >= thing_limit
fail "Limited to #{thing_limit} things")
end
end
end
Esto es Rails. Si tengo que trabajar tan duro, probablemente estoy haciendo algo mal. Para hacer esto, tengo que actualizar el modelo principal, el controlador del niño, ¿Y no puedo seguir la convención? ¿Me estoy perdiendo de algo? ¿Estoy haciendo mal uso dehas_many, :before_add
? Busqué un ejemplo usando: before_add, pero no pude encontrar ninguno.
Pensé en mover la validación a Usuario, pero eso solo ocurre en Guardar / actualizar usuario. No veo una manera de usarlo para detener la adición de una Cosa.
Prefiero una solución para Rails 3 (si eso es importante para este problema).