2012-01-15 15 views
6

Estoy utilizando Rails 3.1.0 y me gustaría "tocar" un modelo principal de una asociación belongs_to solo si se cumplen ciertas condiciones.¿Cómo "tocar" un modelo principal de una asociación `belongs_to` solo si se cumplen ciertas condiciones?

Por ejemplo, en este momento tengo:

belongs_to :article, 
    :touch => true 

que habría "toque" el modelo de los padres sólo si es "público". Es decir, la clase Article tiene un atributo llamado access (@article.access =>public o private) y me gustaría comprobar este valor antes de "tocar": si este valor es no public, a continuación, "toque" que!

¿Es posible hacer eso "directamente" en la declaración de asociación belongs_to? ¿Si es así, cómo?

Respuesta

4

Usted puede tratar de lambda como usted ha dicho, pero No estoy seguro si va a funcionar. Algo como esto:

belongs_to :article, :touch => Proc.new{|o| o.article && o.article.public } 

De acuerdo con la implementation tal vez usted puede tratar de volver nil en lugar de false en el proc, cuando no está disponible

belongs_to :article, :touch => Proc.new{|o| o.article && o.article.public ? true : nil } 

Si esto no funciona utilizan una antes de guardar devolución de llamada de esta manera:

class Model < ActiveRecord::Base 
    belongs_to :article 

    before_save :touch_public_parent 

    def touch_public_parent 
    article.touch if article && article.public? 
    end 
end 

Avíseme si tiene alguna pregunta.

Actualización # 1

La parte pertinente de add_touch_callbacks:

if touch_attribute == true 
    association.touch unless association.nil? 
else 
    association.touch(touch_attribute) unless association.nil? 
end 

Así que si pasa cierto, entonces hace un simple toque en updated_at atributo. Si pasa un nombre de campo, entonces actualiza ese campo a menos que pase nil. Si pasa nil no actualiza nada. Es por eso que dije que tal vez puedas probar la segunda versión de la asociación belongs_to.

+0

No hay documentación relacionada con el método 'add_touch_callbacks' que vinculó en su respuesta ... ¿puede decir algo más al respecto (por ejemplo, cómo funciona)? – Backo

+0

@Backo Claro, por favor vea mi respuesta actualizada. – dombesz

+0

Muchas gracias. ¡Te veo la próxima pregunta/respuesta! – Backo

0

No creo que pueda aplicar touch con una condición en una asociación belongs_to.

Hay una manera que es un poco hacky pero trabajará directamente con una asociación belongs_to,

esto puede no ser la forma recomendada

 
class YourModel 
    belongs_to :article 
    belongs_to :public_article, :class_name=> "Article", 
      :foreign_key => "article_id", 
      :conditions => {:public => true} , :touch => true 
end 
+0

¿Es posible usar algunos 'Proc' /' lambda' en el valor de la opción ': touch'? – Backo

+0

no no puede usar un proceso o una lambda, citando de la documentación, ": touch => Si es verdadero, se tocará el objeto asociado (los atributos updated_at/on establecidos en este momento) cuando este registro sea guardado o destruido. Si especifica un símbolo, ese atributo se actualizará con la hora actual además del atributo updated_at/on ". –

+0

Acabo de abrir otra pregunta para llegar a otra solución: http://stackoverflow.com/questions/8872045/there-is-a-way-to-handle-after-save-and-after-destroy-equally. – Backo

Cuestiones relacionadas