Tengo los siguientes modelos:
Table name: seasons
id :integer not null, primary key
league_id :integer not null
date :integer not null
actual_round :integer default(0), not null
created_at :datetime
updated_at :datetime
class Season < ActiveRecord::Base
has_many :rounds, :dependent => :destroy
end
Table name: rounds
id :integer not null, primary key
season_id :integer not null
round_number :integer not null
created_at :datetime
updated_at :datetime
class Rounds < ActiveRecord:Base
belongs_to :season
end
El caso es que actual_round apunta a una instancia de round para saber
cual es la jornada actual de la temporada, me gustarÃa saber si es
posible establecer también una relación has_one en season hacia rounds a
través del campo actual_round.
Gracias.
Carlos Belizón wrote:
El caso es que actual_round apunta a una instancia de round para saber
cual es la jornada actual de la temporada, me gustarÃa saber si es
posible establecer también una relación has_one en season hacia rounds a
través del campo actual_round.
Fácil:
class Season < ActiveRecord::Base
has_many :rounds, :dependent => :destroy
has_one :round_actual, :foreign_key => ‘actual_round’
end
Y para acceder:
my_season.rounds
my_season.round_actual
fÃjate y no pongas has_one :actual_round , porque si no rails no podrá
saber si te refieres al campo o al objeto, y te dará problemas.
s2
Bueno, quizás no me expliqué todo lo bien que debÃa, vuelvo a explicarme
de forma más extensa:
Tengo una clase llamada Season que está relacionada con Round en una
relación de este tipo:
class Season < ActiveRecord::Base
has_many :rounds
end
class Round < ActiveRecord::Base
belongs_to :season
end
Esa relación funciona perfectamente.
Dentro del modelo season tengo un campo llamado actual_round el cuál
guarda el id de una Round (de la jornada actual del campeonato vamos), y
resulta que una Season sólo puede tener una Round como jornada actual.
Si hago esto:
class Season < ActiveRecord::Base
has_many :rounds
has_one :round_actual, :foreign_key => ‘actual_round’
end
class Round < ActiveRecord:::Base
belongs_to :season
end
Cuando hago my_season.round_actual recibo el error siguiente:
uninitialized constant Season::RoundActual
¿Es realmente posible hacer lo que estoy haciendo o no?
Fernando C. wrote:
Carlos Belizón wrote:
El caso es que actual_round apunta a una instancia de round para saber
cual es la jornada actual de la temporada, me gustarÃa saber si es
posible establecer también una relación has_one en season hacia rounds a
través del campo actual_round.
Fácil:
class Season < ActiveRecord::Base
has_many :rounds, :dependent => :destroy
has_one :round_actual, :foreign_key => ‘actual_round’
end
Y para acceder:
my_season.rounds
my_season.round_actual
fÃjate y no pongas has_one :actual_round , porque si no rails no podrá
saber si te refieres al campo o al objeto, y te dará problemas.
s2
Cuando intento acceder a my_season.round_actual me dá el siguiente
error:
uninitialized constant Season::RoundActual
¿Qué estaré haciendo mal?
2009/5/7 Carlos Belizón [email protected]
Si el campo lo guardas en Season, no te puede funcionar como clave
foránea
en Round, que es lo que tú estás diciendo
Tal como lo tienes montado, la jornada actual la tienes en
current_round =
@current_season.rounds.find(@current_season.actual_round)
que lo puedes pasar a un método de Season
season.rb
class Season < ActiveRecord::Base
has_many :rounds
def current_round
rounds.find(actual_round)
end
end
@season.current_round ya teda la actual
-
Por cierto, “actual” en inglés, si no me equivoco, es más bien
“verdadera”. La actual serÃa “current” or “present”
-
Supongo que es equivalente y va en gustos, pero yo preferiria guardar
un
booleano “current” en Round y simplemente asegurarme de que se pone y se
quita correctamente. Asà puedes usar un named_scope :current
Y por cierto, en algún momento, cambia las claves foráneas para que
acaben
en “_id”, se entiende todo mucho mejor
Post Data
Como bien dicen mis compañeros, también puedes poner un belongs_to
:current_round, :class_name => ‘Round’, :foreign_key => ‘actual_round’
en
Seson. De forma que también podrÃas hacer @current_season.current_round,
pero nos parece semánticamente raruno
Manuel González Noriega wrote:
2009/5/7 Carlos Belizón [email protected]
Como bien dicen mis compañeros, también puedes poner un belongs_to
:current_round, :class_name => ‘Round’, :foreign_key => ‘actual_round’
en
Seson. De forma que también podrÃas hacer @current_season.current_round,
pero nos parece semánticamente raruno
Oooops!! esto es exactamente lo que yo querÃa decir, pero me habÃa
dejado el :class_name => ‘Round’, y claro… no funcionaba!!
A mà no me parece semánticamente raruno; a mà me encanta… y de hecho,
lo uso. Pero eso son gustos personales… aunque desde luego, es más
corto de escribir y más eficiente a nivel BBDD que
@current_season.rounds.find(@current_season.actual_round)
s2
Manuel González Noriega wrote:
2009/5/7 Carlos Belizón [email protected]
Si el campo lo guardas en Season, no te puede funcionar como clave
foránea
en Round, que es lo que tú estás diciendo
Tal como lo tienes montado, la jornada actual la tienes en
current_round =
@current_season.rounds.find(@current_season.actual_round)
que lo puedes pasar a un método de Season
season.rb
class Season < ActiveRecord::Base
has_many :rounds
def current_round
rounds.find(actual_round)
end
end
@season.current_round ya teda la actual
He optado por implementar esta opción y otro método asÃ:
def current_round=(other)
actual_round = other.id
end
- Por cierto, “actual” en inglés, si no me equivoco, es más bien
“verdadera”. La actual serÃa “current” or “present”
Toda la razón, esto me pasa por no tener mucha idea de inglés :).
- Supongo que es equivalente y va en gustos, pero yo preferiria guardar
un
booleano “current” en Round y simplemente asegurarme de que se pone y se
quita correctamente. Asà puedes usar un named_scope :current
Pero es tener un campo replicado por todas partes (mala normalización) y
el problema es que esta aplicación es de PFC y como que los profesores
de BBDD se ponen muy pejigueras.
Y por cierto, en algún momento, cambia las claves foráneas para que
acaben
en “_id”, se entiende todo mucho mejor
El problema es que en este caso he ido cambiándolo sobre la marcha :).
Post Data
Como bien dicen mis compañeros, también puedes poner un belongs_to
:current_round, :class_name => ‘Round’, :foreign_key => ‘actual_round’
en
Seson. De forma que también podrÃas hacer @current_season.current_round,
pero nos parece semánticamente raruno
Eso tiene un problema y es que cuando se implementa hace un select en la
tabla rounds buscando un actual_round cosa que no existe en dicha tabla
:).
Gracias a todos ;).
2009/5/7 Carlos Belizón [email protected]
Mmmmm, confieso que no entiendo, un campo booleano en la tabla Rounds
¿rompe
la normalización? Equivale a cualquier campo “active”, “featured”, o
similar
en otra tabla.
Eso tiene un problema y es que cuando se implementa hace un select en la
tabla rounds buscando un actual_round cosa que no existe en dicha tabla
:).
Si el belongs_to está en Season, no deberÃa esperar el fk en la tabla
“rounds”
2009/5/7 Fernando C. [email protected]
dejado el :class_name => ‘Round’, y claro… no funcionaba!!
Pero tú decÃas ponerlo como has_one, no? El problema asà es que buscarÃa
la
fk en la tabla ‘rounds’ y está en ‘seasons’
A mà no me parece semánticamente raruno; a mà me encanta… y de hecho,
lo uso. Pero eso son gustos personales… aunque desde luego, es más
corto de escribir y más eficiente a nivel BBDD que
@current_season.rounds.find(@current_season.actual_round)
No tengo problema con el has_one, pero hacer ahà que Temporada sea “hija
de”
o “pertenezca a” Jornada, me parece contraintuitivo al invertir la
relación.
En todo caso, sà que es más corto que el find con scope, pero por eso
recomendaba meterlo en un método
Manuel González Noriega wrote:
Mmmmm, confieso que no entiendo, un campo booleano en la tabla Rounds
¿rompe
la normalización? Equivale a cualquier campo “active”, “featured”, o
similar
en otra tabla.
Vale, quizás un flag no sea realmente no normalizar un dato, pero es un
dato repetido en cada jornada que veo bastante innecesario (vamos mi
tutor me ha recomendado quitarlo para que no me pongan pegas) ya que con
un simple “puntero” a la jornada actual solucionas el problema con el
consecuente ahorro de espacio en la BD.
Si el belongs_to está en Season, no deberÃa esperar el fk en la tabla
“rounds”
Probaré eso, para ver como funciona y te cuento :).