hello,
I have an m:n relationsship (has_and_belongs_to_many) between the models
CoreUser and CoreGroup. So from some rails experience I thought I''d
be able to add a (user,group)-relation simply by doing
agroup.core_users << auser.
Unfortunately the following test-case fails on the last assertion
(unless I include the line that is commented out):
def test_add_remove
someuser = CoreUser.create!(:username => ''test2s'', ...)
ag = CoreGroup.find_by_path("/Administrators")
assert !ag.core_users.include?(someuser)
assert !someuser.core_groups.include?(ag)
ag.core_users << someuser
# someuser.core_groups << ag
assert ag.core_users.include?(someuser)
assert someuser.core_groups.include?(ag)
end
Shouldn''t it work with the line being commented out (one direction)?
The models look like this:
class CoreUser < ActiveRecord::Base
has_one :core_page
has_many :core_artifacts
has_many :core_rating1s
has_many :core_rating2s
has_many :core_messages
has_many :core_widgets
has_and_belongs_to_many :core_groups
validates_presence_of :username, :first_name, :last_name, :email_address,
:password_hash
validates_uniqueness_of :username, :email_address
[...]
class CoreGroup < ActiveRecord::Base
has_one :core_page
has_and_belongs_to_many :core_users
acts_as_tree :order => :name # sort children by :name
validates_presence_of :name
validates_uniqueness_of :name, :scope => :parent_id
thanks,
--
Felix Natter
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
Felix Natter <felix.natter-HLWg83l9DMfnMc1oM6GxaBvVK+yQ3ZXh-XMD5yJDbdMReXY1tMh2IBg@public.gmane.org> writes:> hello, > > I have an m:n relationsship (has_and_belongs_to_many) between the models > CoreUser and CoreGroup. So from some rails experience I thought I''d > be able to add a (user,group)-relation simply by doing > agroup.core_users << auser. > > Unfortunately the following test-case fails on the last assertion > (unless I include the line that is commented out): > > def test_add_remove > someuser = CoreUser.create!(:username => ''test2s'', ...) > ag = CoreGroup.find_by_path("/Administrators") > assert !ag.core_users.include?(someuser) > assert !someuser.core_groups.include?(ag) > > ag.core_users << someuser > # someuser.core_groups << ag > assert ag.core_users.include?(someuser) > assert someuser.core_groups.include?(ag) > end > > Shouldn''t it work with the line being commented out (one direction)? > > The models look like this: > > class CoreUser < ActiveRecord::Base > > has_one :core_page > > > has_many :core_artifacts > has_many :core_rating1s > has_many :core_rating2s > has_many :core_messages > has_many :core_widgets > has_and_belongs_to_many :core_groups > > validates_presence_of :username, :first_name, :last_name, :email_address, :password_hash > validates_uniqueness_of :username, :email_address > [...] > > class CoreGroup < ActiveRecord::Base > > has_one :core_page > > has_and_belongs_to_many :core_users > acts_as_tree :order => :name # sort children by :name > > > validates_presence_of :name > validates_uniqueness_of :name, :scope => :parent_id >here is some additional information from a console session: mysql> select * from core_groups_core_users; +---------------+--------------+ | core_group_id | core_user_id | +---------------+--------------+ | 1 | 1 | | 2 | 2 | | 2 | 3 | | 2 | 4 | | 4 | 2 | | 5 | 5 | | 5 | 6 | | 5 | 7 | | 5 | 8 | | 9 | 7 | | 6 | 2 | | 7 | 2 | | 6 | 3 | | 8 | 3 | | 12 | 6 | | 12 | 5 | | 10 | 3 | | 11 | 3 | | 10 | 4 | | 11 | 4 | | 17 | 8 | | 13 | 2 | | 14 | 2 | | 13 | 3 | | 15 | 3 | | 13 | 4 | | 16 | 4 | +---------------+--------------+ 27 rows in set (0.00 sec)>> u.core_groups=> [#<CoreGroup id: 1, parent_id: nil, type: "", name: "Administrators", is_open: false, is_system_group: true, rights: "", serialized_custom_data: "BAh7AA==\n", created_at: "2008-02-10 20:25:44", updated_at: "2008-02-10 20:25:44">]>> g.core_users=> [#<CoreUser id: 5, username: "mkaul2m", first_name: "Manfred", last_name: "Kaul", email_address: "manfred.kaul-NckoJsw/TC+zQB+pC5nmwQ@public.gmane.org", password_hash: "5ebe2294ecd0e0f08eab7690d2a6ee69", rights: "", serialized_custom_data: "BAh7AA==\n", num_logins: 0, last_login: nil, created_at: "2008-02-10 20:25:44", updated_at: "2008-02-10 20:25:44">, #<CoreUser id: 6, username: "sbuers2m", first_name: "Simone", last_name: "Bürsner", email_address: "simone.buersner@fh-brs.de", password_hash: "e8636ea013e682faf61f56ce1cb1ab5c", rights: "", serialized_custom_data: "BAh7AA==\n", num_logins: 0, last_login: nil, created_at: "2008-02-10 20:25:44", updated_at: "2008-02-10 20:25:44">, #<CoreUser id: 7, username: "tbreue2m", first_name: "Thomas", last_name: "Breuer", email_address: "thomas.breuer-NckoJsw/TC+zQB+pC5nmwQ@public.gmane.org", password_hash: "699a474e923b8da5d7aefbfc54a8a2bd", rights: "", serialized_custom_data: "BAh7AA==\n", num_logins: 0, last_login: nil, created_at: "2008-02-10 20:25:44", updated_at: "2008-02-10 20:25:44">, #<CoreUser id: 8, username: "vdhude2m", first_name: "Marlis", last_name: "von der Hude", email_address: "marlis.vonderhude-NckoJsw/TC+zQB+pC5nmwQ@public.gmane.org", password_hash: "d1cf6a6090003989122c4483ed135d55", rights: "", serialized_custom_data: "BAh7AA==\n", num_logins: 0, last_login: nil, created_at: "2008-02-10 20:25:44", updated_at: "2008-02-10 20:25:44">] => neither u is in g or g contains u>> g.core_users << umysql> select * from core_groups_core_users; +---------------+--------------+ | core_group_id | core_user_id | +---------------+--------------+ | 1 | 1 | | 2 | 2 | | 2 | 3 | | 2 | 4 | | 4 | 2 | | 5 | 5 | | 5 | 6 | | 5 | 7 | | 5 | 8 | | 9 | 7 | | 6 | 2 | | 7 | 2 | | 6 | 3 | | 8 | 3 | | 12 | 6 | | 12 | 5 | | 10 | 3 | | 11 | 3 | | 10 | 4 | | 11 | 4 | | 17 | 8 | | 13 | 2 | | 14 | 2 | | 13 | 3 | | 15 | 3 | | 13 | 4 | | 16 | 4 | | 5 | 1 | +---------------+--------------+ 28 rows in set (0.00 sec) => the last row has been inserted: User #1 now is in groups 1 and 5 (from a database point of view). However, u.core_groups does not reflect this:>> u.core_groups=> [#<CoreGroup id: 1, parent_id: nil, type: "", name: "Administrators", is_open: false, is_system_group: true, rights: "", serialized_custom_data: "BAh7AA==\n", created_at: "2008-02-10 20:25:44", updated_at: "2008-02-10 20:25:44">] only when I restart the console, the change is seen:>> u.core_groups=> [#<CoreGroup id: 1, parent_id: nil, type: "", name: "Administrators", is_open: false, is_system_group: true, rights: "", serialized_custom_data: "BAh7AA==\n", created_at: "2008-02-10 20:25:44", updated_at: "2008-02-10 20:25:44">, #<CoreGroup id: 5, parent_id: nil, type: "", name: "Lecturers", is_open: false, is_system_group: true, rights: "", serialized_custom_data: "BAh7AA==\n", created_at: "2008-02-10 20:25:44", updated_at: "2008-02-10 20:25:44">] is this normal? Please tell me if you need more information. thanks! -- Felix Natter --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 10 Feb 2008, at 20:33, Felix Natter wrote:> > Felix Natter <felix.natter-HLWg83l9DMfnMc1oM6GxaBvVK+yQ3ZXh-XMD5yJDbdMReXY1tMh2IBg@public.gmane.org > > writes: > > However, u.core_groups does not reflect this: > >>> u.core_groups > => [#<CoreGroup id: 1, parent_id: nil, type: "", name: > "Administrators", is_open: false, is_system_group: true, rights: "", > serialized_custom_data: "BAh7AA==\n", created_at: "2008-02-10 > 20:25:44", updated_at: "2008-02-10 20:25:44">] > > only when I restart the console, the change is seen: >>> u.core_groups > => [#<CoreGroup id: 1, parent_id: nil, type: "", name: > "Administrators", is_open: false, is_system_group: true, rights: "", > serialized_custom_data: "BAh7AA==\n", created_at: "2008-02-10 > 20:25:44", updated_at: "2008-02-10 20:25:44">, #<CoreGroup id: 5, > parent_id: nil, type: "", name: "Lecturers", is_open: false, > is_system_group: true, rights: "", serialized_custom_data: "BAh7AA== > \n", created_at: "2008-02-10 20:25:44", updated_at: "2008-02-10 > 20:25:44">] > > is this normal? >AR is like that. if you set an association, rails does not magically update the other in memory object with the reverse association (but it is there in the database of course). Fred --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
> AR is like that. if you set an association, rails does not magically > update the other in memory object with the reverse association (but it > is there in the database of course).I don''t know if anyone mentioned to throw a ''reload()'' call in somewhere... -- Phlip --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
"Phlip" <phlip2005-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> writes:>> AR is like that. if you set an association, rails does not magically >> update the other in memory object with the reverse association (but it >> is there in the database of course). > > I don''t know if anyone mentioned to throw a ''reload()'' call in somewhere...That was it, thanks to both of you! So I should change this code: clas CoreGroup... def add(user) core_users << user if !core_users.include?(user) end def remove(user) core_users.delete(user) end to this: class CoreGroup... def add(user) core_users << user if !core_users.include?(user) user.save user.reload # make ActiveRecord update relation info end def remove(user) core_users.delete(user) user.save user.reload # make ActiveRecord update relation info end ? Or is there a method to just reload the relation info? thanks in advance, -- Felix Natter --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
> ? Or is there a method to just reload the relation info?I have seen this around: user.core_groups(:reload) If it does what it says, then it only repopulates the controlled array inside core_groups, without reloading the entire user object, or forcing a reload of everything else Insert standard complaint here about how awesome ActiveRecord associations look just before you put a cycle in your code and discover the risk of dirty data bugs! --> [ ] -- Phlip http://assertxpath.rubyforge.org/classes/Assert2_0.html --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Strictly speaking, I don''t believe that it''s necessary to call
save on
the user object. I realize that you''re probably doing this because
the user object may contain unsaved data, but it brings a second
purpose to your method.
Also, if you ever need to use the results of CoreGroup#add or
CoreGroup#remove in subsequent processing then the results are going
to be a little muddied. As coded you will always save/reload the user
regardless of whether the association was added/deleted.
Consequently, the method will always return the result of the
user.reload call. You could get into confusing scenarios if the
results conflicted (e.g., association creaated but reload failed,
association failed but reload succeeded).
Maybe something like this:
def add(user)
return false if core_users.include?(user)
if core_users << user
user.core_groups.reload
return true
end
false
end
For your primary purpose you just need to know that you can call
''reload'' on the association proxy to reload only that
collection. The
rest of the code only guarantees that you get a pass/fail response
related to adding/removing on the collection.
On Feb 10, 4:59 pm, Felix Natter
<felix.nat...-HLWg83l9DMfnMc1oM6GxaBvVK+yQ3ZXh@public.gmane.org>
wrote:> "Phlip" <phlip2...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
writes:
> >> AR is like that. if you set an association, rails does not
magically
> >> update the other in memory object with the reverse association
(but it
> >> is there in the database of course).
>
> > I don''t know if anyone mentioned to throw a
''reload()'' call in somewhere...
>
> That was it, thanks to both of you! So I should change this code:
>
> clas CoreGroup...
> def add(user)
> core_users << user if !core_users.include?(user)
> end
>
> def remove(user)
> core_users.delete(user)
> end
>
> to this:
>
> class CoreGroup...
> def add(user)
> core_users << user if !core_users.include?(user)
> user.save
> user.reload # make ActiveRecord update relation info
> end
>
> def remove(user)
> core_users.delete(user)
> user.save
> user.reload # make ActiveRecord update relation info
> end
>
> ? Or is there a method to just reload the relation info?
>
> thanks in advance,
>
> --
> Felix Natter
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---