I am kindof assuming that this is something of a newbie question as
far as ActiveRecord goes, but I've looked through the documentation on
ar.rubyonrails.org and can't seem to figure it. Any advice would be
much appreciated.
I'm trying to setup a small stats tracking webapp in an attempt to
teach myself rails. (previously I've done web development with JSasp
and Micro$oft products) and I'm happy to say that I'm pleased as punch
with rails. In fact, I've got the site working but I'm using some
pretty hacky calls to ActiveRecord::Base.connection.select_all to pull
data out of the DB and make on my own collections :(.
I have two tables in my DB, one which keeps track of teams and another
which keeps track of matches. (two teams can play a match and there is
one winner and one loser) The difficult bit seems to be that the
team's id can be stored in either one of two columns in the matches
table.
I feel like I should be able to setup the Team model to have a
collection of the matches which that team has participated in and
here's what I've tried so far:
class Team < ActiveRecord::Base
has_many :matchess, :finder_sql =>
"select * from matches " +
"where matches.one = #{id} " +
"or matches.two = #{id}"
end
Now this 'works' but it seems that the id that it is inserting into
the SQL string is the ruby unique id for the Team object that is
created. What I want is the id of the team which is stored in the
database. Is this stored in the Team object anywhere? or am I going at
this all backwards?
Is there a resource somewhere that explains when you should use
has_many vs belongs_to or has_and_belongs_to_many?
I'd be happy to clarify if needed, as I wouldn't be supprised if I've
got this basically all wrong. (:
Thanks in advance,
-Harold
Harold Hausman wrote:
I have two tables in my DB, one which keeps track of teams and another
which keeps track of matches. (two teams can play a match and there is
one winner and one loser) The difficult bit seems to be that the
team's id can be stored in either one of two columns in the matches
table.
I feel like I should be able to setup the Team model to have a
collection of the matches which that team has participated in and
here's what I've tried so far:
class Team < ActiveRecord::Base
has_many :matchess, :finder_sql =>
"select * from matches " +
"where matches.one = #{id} " +
"or matches.two = #{id}"
end
Now this 'works' but it seems that the id that it is inserting into
the SQL string is the ruby unique id for the Team object that is
created. What I want is the id of the team which is stored in the
database. Is this stored in the Team object anywhere? or am I going at
this all backwards?
I haven't used this particular feature of Rails, but I think what you
want is to use single quotes around the SQL snippets rather than double
quotes. Double quotes evaluate #{expressions like this} as soon as
they're created, while ActiveRecord wants to evaluate it later once it
has a Team object to get the id from.
Is there a resource somewhere that explains when you should use
has_many vs belongs_to or has_and_belongs_to_many?
I thought there was, but I can't find it. The difference is basically
this:
X belongs_to Ys: Every X record has a y_id entry identifying which Y it
belongs to.
Y has_many Xs: Has a method that will return all Xs with a y_id equal
to its own.
(Basically, objects that belong to another keep track of their owner.
Telling the owner that it owns them gives it the ability to
automatically find them.)
X has_and_belongs_to_many Ys: This one works differently. Every X can
refer to several Ys, and every Y can refer to several Xs. To do this,
you create a join table where each row represents a relationship
between an X and a Y. This might be a good choice for the relationship
between Matches and Teams, because each team can have many matches and
each match has many teams.
Perfect! This was exactly the problem, perhaps this should be added to
the activeRecord documentation (or be made more prominent if its
already in there somewhere).
Now another question. Now that each match that the team has
participated in is associated with the team it would be really handy
if the teams involved in each match were associated with that match
(so I can have access to their human readable names and such.) Heres
what I tried:
class Match < ActiveRecord::Base
has_one :team_one, :class_name => "Team", :conditions => 'id = #{one}'
has_one :team_two, :class_name => "Team", :conditions => 'id = #{two}'
end
*note: 'one' and 'two' are the names of the columns in the matches
table where I store the team ids that participated in the match.
What I was hoping was that each Match object would then have two new
child objects called team_one and team_two which would be Team
objects. This did not work, near as I can tell it formulated some sql
string which contained some match_id gibberish in the where clause and
there is no match_id column in the teams table. (maybe this is how I'm
supposed to know to use has_and_belongs_to_many)
What I've ended up doing is using has_many, and then using :finder_sql
to completely override the sql statement to select just the team I'm
looking for which works and creates a single element array but results
in some slightly hack-ish useage of operator passing 0 to get the
first object (i.e. match.team_one[0]["name"] ) which isint a big deal
at all.
But... It seems to me that it might be valuable to have :finder_sql as
an option for has_one for situations like this where I don't want to
bother with another table just to associate teams with matches and use
has_and_belongs_to_many.
Sorry for the rambling post, and thanks kindly for the quick-like and
useful/accurate response on the single vs. double quote thing. Long
live this community and rails and everything else sweet in this world.
(:
-Harold
···
On 6/5/05, Charles Steinman <acharlieblue@gmail.com> wrote:
Harold Hausman wrote:
> I have two tables in my DB, one which keeps track of teams and another
> which keeps track of matches. (two teams can play a match and there is
> one winner and one loser) The difficult bit seems to be that the
> team's id can be stored in either one of two columns in the matches
> table.
>
> I feel like I should be able to setup the Team model to have a
> collection of the matches which that team has participated in and
> here's what I've tried so far:
>
> class Team < ActiveRecord::Base
> has_many :matches, :finder_sql =>
> "select * from matches " +
> "where matches.one = #{id} " +
> "or matches.two = #{id}"
> end
>
> Now this 'works' but it seems that the id that it is inserting into
> the SQL string is the ruby unique id for the Team object that is
> created. What I want is the id of the team which is stored in the
> database. Is this stored in the Team object anywhere? or am I going at
> this all backwards?
I haven't used this particular feature of Rails, but I think what you
want is to use single quotes around the SQL snippets rather than double
quotes. Double quotes evaluate #{expressions like this} as soon as
they're created, while ActiveRecord wants to evaluate it later once it
has a Team object to get the id from.
http://api.rubyonrails.com/classes/ActiveRecord/Associations/ClassMethods.html
Though you are better off viewing it with frames via:
http://api.rubyonrails.com/
Douglas
···
On 6/6/05, Charles Steinman <acharlieblue@gmail.com> wrote:
Harold Hausman wrote:
>
> Is there a resource somewhere that explains when you should use
> has_many vs belongs_to or has_and_belongs_to_many?
I thought there was, but I can't find it. The difference is basically
this:
You want to have:
class Match < ActiveRecord::Base
belongs_to :team_one, ...
belongs_to :team_two, ...
end
belongs_to signifies that the foreign key column is in THIS table, ie
the table of the same model. has_one signifies that the foreign key
column is in the table of the related model.
Very common mistake. But I believe there is significant documentation
to explain why the relations are named as they are though.
Hope that helps.
BTW, there is a mailing list specifically for Ruby On Rails [1], which
would be more appropriate for these questions than ruby-talk.
Jason
[1] http://lists.rubyonrails.org/mailman/listinfo/rails
···
On 6/6/05, Harold Hausman <hhausman@gmail.com> wrote:
..
class Match < ActiveRecord::Base
has_one :team_one, :class_name => "Team", :conditions => 'id = #{one}'
has_one :team_two, :class_name => "Team", :conditions => 'id = #{two}'
end
*note: 'one' and 'two' are the names of the columns in the matches
table where I store the team ids that participated in the match.
What I was hoping was that each Match object would then have two new
child objects called team_one and team_two which would be Team
objects. This did not work, near as I can tell it formulated some sql
string which contained some match_id gibberish in the where clause and