Relación entre modelos

Buenas tardes a todos,
estoy realizando una aplicación para iniciarme en Rails, y me surge la
siguiente duda. Considerando los siguientes modelos:

Table name: users

id :integer(11) not null, primary key

name :string(255)

class User < ActiveRecord::Base
has_many :tickets
end

Table name: tickets

id :integer(11) not null, primary key

lock_version :integer(11) default(0)

subject :string(255)

body :text

priority :integer(11)

status :string(255)

user_id :integer(11)

class Ticket < ActiveRecord::Base
belongs_to :user
end

Esta relación me funciona perfectamente. Lo que quiero conseguir ahora
es que los usuarios puedan subscribirse a un o varios tickets, de modo
que cuando se actualicen, reciban un email indicando que ha cambiado de
estado.

¿Como lo puedo conseguir?
Creo que lo ideal sería una relación muchos a muchos (habtm), pero no se
como crearla para que no interfiera en la anterior relación.

Gracias a todos.

¿Como lo puedo conseguir?
Creo que lo ideal sería una relación muchos a muchos (habtm), pero no se
como crearla para que no interfiera en la anterior relación.

Lo que puedes hace ahora es:
User.tickets

Eso es un array y puede ser de un ticket o muchos tickets.

Un ticket:
User.tickets[0]

No creo que necesitas many to many. Except el caso que un ticket tienes
muchos users. Por ejemplo, si es un ticket for a group of users.

hth
Toby

On 3/19/07, Jose [email protected] wrote:

end
class Ticket < ActiveRecord::Base
belongs_to :user
end

o sea que un ticket tiene un usuario como “owner” y luego cualquier
usuario se puede suscribir? quizás algo
así:

subscriptions es un modelo como cualquiera, con id autonumérico, y las

dos FKs
class Subscription < ActiveRecord::Base
belongs_to :ticket
belongs_to :user
end

class User < ActiveRecord::Base
has_many :tickets
has_many :subscription_tickets, :through => :subscriptions, :source =>
:ticket
end

class Ticket < ActiveRecord::Base
belongs_to :user
belongs_to :subscription
end

Damian J. wrote:

subscriptions es un modelo como cualquiera, con id autonum�rico, y las

dos FKs
class Subscription < ActiveRecord::Base
belongs_to :ticket
belongs_to :user
end

class User < ActiveRecord::Base
has_many :tickets
has_many :subscription_tickets, :through => :subscriptions, :source =>
:ticket
end

class Ticket < ActiveRecord::Base
belongs_to :user
belongs_to :subscription
end

Hola Damian, exactamente eso mismo estaba intentando ahora:

class Ticket < ActiveRecord::Base
belongs_to :user

has_many :subscribers
has_many :users_subscribed ,:through => :subscribers, :source => :user

class User < ActiveRecord::Base
has_many :tickets

has_many :subscribers
has_many :tickets_subscribed ,:through => :subscribers, :source =>
:ticket

He creado en la Vista (tickets/_form.rhtml):

User watching this ticket

<%= start_form_tag :action => 'update_subscribers', :id => @ticket %> <% User.find(:all).each do |user| %> <%= check_box_tag("users_subscribed[]", user.id, @ticket.users_subscribed.include?(user)) %><%= user.name %>
<% end %> <%= submit_tag 'Save changes' %> <%= end_form_tag %>

Y en el controlador:

def update_subscribers
@ticket = Ticket.find(params[:id])
@ticket.users_subscribed.clear
User.find(params[:users_subscribed]).each do |user|
@ticket.users_subscribed << user
end
@ticket.save
redirect_to :action => ‘show’, :id => @ticket
end

Pero no me guarda los cambios, algo tendrá mal este método.

Si te entiendo, pero no me refería a eso exactamente:

  • Un usuario puede crear tantos ticket como quiera, de ahí que la tabla
    Ticket tenga el user_id, haciendo referencia al usuario que lo ha
    creado.
  • Mi problema ahora es que quiero implementar que un usuario pueda
    subscribirse a uno o varios tickets, de modo que cuando estos sean
    modificados se avise con un correo. Había pensado en una tabla
    user_tickets, donde podré ver para casa ticket que usuarios están
    esperando de ser avisados.

Esto último es lo que intento conseguir, lógicamente, lo anterior es un
habtm, si lo implemento quedaría:

class User < ActiveRecord::Base
has_many :tickets
has_and_belongs_to_many :tickets
end

Creando conflicto.

Damian J. wrote:

On 3/19/07, Jose [email protected] wrote:

Si te entiendo, pero no me refer�a a eso exactamente:

No s� si la respuesta fue a m� o a tobby, pero lo que yo te envi� es
justamente para hacer esta relaci�n “muchos a muchos” pero “a la Rails
1.2”

has_and_belongs_to_many no nos gusta m�s :slight_smile:

Hola Damian,
mientras escribía mi respuesta a tobby, posteaste tu y te colaste.
Ahora mientras te respondía a tí, volviste a postear :wink:
Arriba puedes encontrar mi respuesta.

Gracias.

On 3/19/07, Jose [email protected] wrote:

end

Otra implicancia de has_many :through es que te ayuda a pensar más en
CRUD.

Mejor si pensás este proceso como un alta masivo de Suscriptions:

ticket = Ticket.find(params[:id])
ticket.subscriptions.clear
params[:users_subscribed].each do |user|
Subscription.create(:ticket_id => ticket.id, :user_id => user)
end

Anda?

Damian J. wrote:

On 3/19/07, Jose [email protected] wrote:

end

Otra implicancia de has_many :through es que te ayuda a pensar m�s en
CRUD.

Mejor si pens�s este proceso como un alta masivo de Suscriptions:

ticket = Ticket.find(params[:id])
ticket.subscriptions.clear
params[:users_subscribed].each do |user|
Subscription.create(:ticket_id => ticket.id, :user_id => user)
end

Anda?

Hola Damian,
vamos a mejor…ahora me guarda los cambios, pero si luego quiero quitar
algún usuario no lo quita. Supongo que será algo del
ticket.subscriptions.clear.
¿Será mejor realizar una búsqueda de todas las Subscriptions que
pertenezcan al ticket y nos las cargamos a saco?

Gracias.

On 3/19/07, Jose [email protected] wrote:

Hola Damian,
vamos a mejor…ahora me guarda los cambios, pero si luego quiero quitar
algún usuario no lo quita. Supongo que será algo del
ticket.subscriptions.clear.
¿Será mejor realizar una búsqueda de todas las Subscriptions que
pertenezcan al ticket y nos las cargamos a saco?

Es que el ticket.subscriptions.clear debería hacer eso :frowning:

De todos modos, es éste un caso de uso de tu aplicación? Es decir, no
deberías modelar las pantallas más acorde a “el usuario A ingresa al
sistema, busca los tickets y se suscribe a uno”, o “el usuario A ve
sus suscripciones y decide eliminar una de ellas”?

Creo que es más lógico (y más fácil de implementar :P)

Muchas gracias Damian,
dejo aquí el código por si le puede interesar a alguien:

def update_subscribers
@ticket = Ticket.find(params[:id])
Subscriber.find(:all, :conditions => [‘ticket_id = ?’,
@ticket.id]).each do |subscriber|subscriber.destroy end
params[:users_subscribed].each do |user|
Subscriber.create(:ticket_id => @ticket.id, :user_id => user)
end unless params[:users_subscribed].nil?
@ticket.save
redirect_to :action => ‘show’, :id => @ticket
end

Un saludo.

On 3/19/07, Jose [email protected] wrote:

@ticket.save
redirect_to :action => 'show', :id => @ticket

end

Solamente para embellecer:

Subscriber.find_all_by_ticket_id(@ticket.id).each &:destroy

Damian J. wrote:

On 3/19/07, Jose [email protected] wrote:

@ticket.save
redirect_to :action => 'show', :id => @ticket

end

Solamente para embellecer:

Subscriber.find_all_by_ticket_id(@ticket.id).each &:destroy

Genial,
alucino las cosas que se pueden llegar a realizar con Rails, que
brutalidad !

Muchas gracias.

On 3/19/07, Jose [email protected] wrote:

Si te entiendo, pero no me refería a eso exactamente:

No sé si la respuesta fue a mí o a tobby, pero lo que yo te envié es
justamente para hacer esta relación “muchos a muchos” pero “a la Rails
1.2”

has_and_belongs_to_many no nos gusta más :slight_smile: