2010-06-21 14 views
9

Similar a this question, ¿cómo configuro una propiedad en el modelo de unión justo antes de guardar en este contexto?Rails has_many: through y Setting Property on Join modelo

class Post < ActiveRecord::Base 
    has_many :post_assets 
    has_many :assets, :through => :post_assets 
    has_many :featured_images, :through => :post_assets, :class_name => "Asset", :source => :asset, :conditions => ['post_assets.context = ?', "featured"] 

end 

class PostAssets < ActiveRecord::Base 
    belongs_to :post 
    belongs_to :asset 

    # context is so we know the scope or role 
    # the join plays 
    validates_presences_of :context 
end 

class Asset < ActiveRecord::Base 
    has_many :post_assets 
    has_many :posts, :through => :post_assets 
end 

Yo sólo quiero ser capaz de hacer esto:

@post = Post.create!(:title => "A Post") 
@post.featured_images << Asset.create!(:title => "An Asset") 
# ... 
@post = Post.first 
@featured = @post.featured_images.first 
    #=> #<Asset id: 1, title: "An Asset"> 
@featured.current_post_asset #=> #<PostAsset id: 1, context: "featured"> 

Cómo funcionaría eso? He estado golpeando mi cabeza todo el día :).

¿Qué ocurre actualmente es cuando hago esto:

@post.featured_images << Asset.create!(:title => "An Asset") 

A continuación, el modelo se unen PostAsset que se crea nunca tiene la oportunidad de establecer context. ¿Cómo configuro esa propiedad de contexto? Se ve así:

PostAsset.first #=> #<PostAsset id: 1, context: nil> 

actualización:

He creado una prueba gem para intentar aislar el problema. ¡¿Hay alguna forma más fácil de hacer esto?!

Esto ActsAsJoinable::Core class lo hace para que pueda tener muchas relaciones con un contexto entre ellas en el modelo de unión. Y agrega métodos de ayuda. El tests básico muestra básicamente lo que intento hacer. ¿Alguna mejor idea sobre cómo hacer esto correctamente?

+0

Esto también parece similar a mi pregunta principios de esta semana: http://stackoverflow.com/questions/3035064/updating-extra-attributes-in-a-has-many-through-relationship-using-rails Solo cambio retroactivamente el modelo de unión.Supongo que debe haber una devolución de llamada, sin embargo, para trabajar en el modelo de unión antes de que se guarde. +1 porque tengo curiosidad. – Robbie

+0

hay una devolución de llamada 'before_add' y' after_add' en el modelo non-join (así 'assets' en el Post), pero no se puede acceder al modelo join de ninguna manera sin llamar a' PostAsset.first (: conditions = > {...}) '. Parece que es una característica que falta en Rails después de leer todos los foros. –

Respuesta

1

vistazo a las opciones has_many en el ActiveRecord :: Asociaciones :: ClassMethods API se encuentra aquí: http://rails.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#M001316

Esta es la cita más interesante:

: condiciones

Especificar el condiciones que el objeto asociado debe cumplir para ser incluido como un fragmento WHERE SQL, como autorizado = 1. Las creaciones de registro de la asociación tienen un alcance si se utiliza un hash. has_many: posts,: conditions => {: published => true} creará publicaciones publicadas con @ blog.posts.create o @ blog.posts.build.

Así que creen sus condiciones deben especificarse como un hash, así:

class Post < ActiveRecord::Base 
    has_many :post_assets 
    has_many :featured_post_assets, :conditions => { :context => 'featured' } 

    has_many :assets, :through => :post_assets 

    has_many :featured_images, :through => :featured_post_assets, 
      :class_name => "Asset", :source => :asset, 
end 

Y también se debe hacer lo siguiente:

@post.featured_images.build(:title => "An asset") 

en lugar de:

@post.featured_images << Asset.create!(:title => "An Asset") 

Esto debería llamar a la creación de activos con ámbito, como se sugiere en th Cita arriba para agregar el campo de contexto al activo. También guardará tanto el objeto de modelo de unión (post_asset) como el objeto de activo a la base de datos al mismo tiempo en una transacción atómica.

+0

Parece que debería funcionar. – thomasfedb

+0

¿qué pasa con '@post.featured_images << Asset.first' y related (en realidad no construir/crear)? –

+0

Estoy bastante seguro de que build no guarda el nuevo registro hasta que se guarda el objeto @post. << guardará el nuevo objeto antes de que se guarde el objeto @post, create hará lo mismo. –

Cuestiones relacionadas