One of the great advantages of relational modelling (over typical object
modelling) is the ability to easily extend an association (i.e. an
association table) with properties of the association itself. In
general O/R mappings make this very difficult to access or take
advantage of. RoR certainly makes the association properties available
by grabbing the association properties due to their participation in the
join, but I haven’t yet figured out how to manage update of these
properties.
An example of this is below. The question is, how can I update
‘indirect_count’, ‘created_at’ and created_by properties of the
association table when I add a member to a group? Do I need to add the
proper instance variables to the Actor object that I am adding to the
members set? Or do I need to go to the SQL itself? Maybe this should
be a FAQ?
— MySQL —
CREATE TABLE users ( id int(11) NOT NULL auto_increment, type varchar(16) default ‘null’,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I think maybe you are overcomplicating it…here’s a simple example of
(i
think) what you are trying to accomplish. It’s possible I’m not
understanding as well, so correct me if I am wrong.
users
id
name
created_at
groups
id
name
creator_id
created_at
groups_users (join table)
group_id
user_id
date_joined
class User < ActiveRecord::Base
has_and_belongs_to_many :groups
def join_group(group, creator)
groups.push_with_attributes(group, :date_joined => Time.now, :creator_id
=>
creator.id http://creator.id)
end
end
class Group < ActiveRecord::Base
has_and_belongs_to_many :users
def add_user(user, creator)
users.push_with_attributes(user, :date_joined => Time.now, :creator_id
=>
creator.id http://creator.id)
end
end
this way you can do:
user = User.create(:name => “Bob”)
group = Group.create(:name => “Geeks-R-Us”)
add a user/group association
user.join_group(group, user)
or group.add_user(user, user)
how many users in each group
groups = Group.find(:all)
groups.each do { |g| puts “group: #{g.name http://g.name}, members: #{
g.users.size}” }
I think maybe you are overcomplicating it…here’s a simple example of
(i think) what you are trying to accomplish. It’s possible I’m not
understanding as well, so correct me if I am wrong.
Actually, I’m not overcomplicating it, but ‘push_with_attributes’ is the
right answer it seems. Since a Group can contain other groups, I need
the inheritance I showed. Thanks for the pointer. It’s still a bit
annoying that I have to make explicit reference to ‘creator_id’, but
that’s the price of putting this information into the association table.
Can you specify the operations you want to do with some fixtures and
test cases?
fixtures:
G 1,2 (group 1 belongs to group 2)
G 1,3
G 4,3
G 4,5
U 6,4 (user 6 belongs to group 4)
tests:
UserBelongsToGroup(6,1)=false
UserBelongsToGroup(6,2)=false
UserBelongsToGroup(6,3)=true
UserBelongsToGroup(6,4)=true
UserBelongsToGroup(6,5)=true
UsersGroups(6)=[3,4,5] (All groups a user belongs to)
GroupsUsers(3)=[6] (All users belonging to a group)
The tables are ok, presuming Type is used to separate between user and
group.
After your confirmation, it’s possible to dig into implementation.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.