Hi everybody, here is my problem. I have a Post model, a Tag model, and they are related to each other by an has_and_belongs_to_many relationship. Now I run ./script/console: p=Post.new p.title="Hello" p.save t=Tag.new t.name="tag1" p.tags = [t] The result is that a Post record is created and saved, and then also a Tag record is created and saved, together with a record in the join table posts_tags. The question is: why are the tag and the record in the join table saved? Shouldn''t they wait for an explicit save? To be more clear, why the last line ( p.tags=[t] ) triggers the creation in the database of a record in the tags table and another in the posts_tags table? Is there a way from stopping this until an explicit save occurs? I hope someone can answer my question, I''m quite a rails newbie so I need help. Thanks. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Ci. wrote:> Hi everybody, > here is my problem. > > I have a Post model, a Tag model, and they are related to each other > by an has_and_belongs_to_many relationship. > > Now I run ./script/console: > > p=Post.new > p.title="Hello" > p.save > > t=Tag.new > t.name="tag1" > p.tags = [t] > > The result is that a Post record is created and saved, and then also a > Tag record is created and saved, together with a record in the join > table posts_tags. > The question is: why are the tag and the record in the join table > saved? Shouldn''t they wait for an explicit save? > To be more clear, why the last line ( p.tags=[t] ) triggers the > creation in the database of a record in the tags table and another in > the posts_tags table? Is there a way from stopping this until an > explicit save > occurs? > > I hope someone can answer my question, I''m quite a rails newbie so I > need help. Thanks.I searched the rails api http://api.rubyonrails.org/ and look into the module ActiveRecord::Associations::ClassMethods And I found the following words that may be helpful * Adding an object to a collection (has_many or has_and_belongs_to_many) automatically saves that object, except if the parent object (the owner of the collection) is not yet stored in the database. * If saving any of the objects being added to a collection (via push or similar) fails, then push returns false. * You can add an object to a collection without automatically saving it by using the collection.build method (documented below). * All unsaved (new_record? == true) members of the collection are automatically saved when the parent is saved. Please Contact me ,i''m a newbie too... and wanna a friend MSN:ikari.shinji.eva-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Yes, I''ve read that page in the rails API, but.. yet, I haven''t found a way to get around this problem.. I was quite enthusiastic about rails until now, but now I''m getting cold. If such an obvious thing is so difficult to do, maybe it''s not the right framework to use.. I don''t know.. On 2 Mar, 03:59, Ikari Shinji <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> Ci. wrote: > > Hi everybody, > > here is my problem. > > > I have a Post model, a Tag model, and they are related to each other > > by an has_and_belongs_to_many relationship. > > > Now I run ./script/console: > > > p=Post.new > > p.title="Hello" > > p.save > > > t=Tag.new > > t.name="tag1" > > p.tags = [t] > > > The result is that a Post record is created and saved, and then also a > > Tag record is created and saved, together with a record in the join > > table posts_tags. > > The question is: why are the tag and the record in the join table > > saved? Shouldn''t they wait for an explicit save? > > To be more clear, why the last line ( p.tags=[t] ) triggers the > > creation in the database of a record in the tags table and another in > > the posts_tags table? Is there a way from stopping this until an > > explicit save > > occurs? > > > I hope someone can answer my question, I''m quite a rails newbie so I > > need help. Thanks. > > I searched the rails apihttp://api.rubyonrails.org/and look into the > module ActiveRecord::Associations::ClassMethods > And I found the following words that may be helpful > > * Adding an object to a collection (has_many or > has_and_belongs_to_many) automatically saves that object, except if the > parent object (the owner of the collection) is not yet stored in the > database. > * If saving any of the objects being added to a collection (via push > or similar) fails, then push returns false. > * You can add an object to a collection without automatically saving > it by using the collection.build method (documented below). > * All unsaved (new_record? == true) members of the collection are > automatically saved when the parent is saved. > > Please Contact me ,i''m a newbie too... and wanna a friend > MSN:ikari.shinji....-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org > -- > Posted viahttp://www.ruby-forum.com/.--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Accoring to the API docs Ikari posted above, you can add a tag to the p model either by using the collection.build method:> > * You can add an object to a collection without automatically saving > > it by using the collection.build method (documented below).or by not saving your p object before adding the tag:> > * Adding an object to a collection (has_many or > > has_and_belongs_to_many) automatically saves that object, except if the > > parent object (the owner of the collection) is not yet stored in the > > database.The API docs contain the answers right there, the way around your problem is there. On Mar 2, 11:28 am, "Ci." <cicci...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Yes, I''ve read that page in the rails API, but.. yet, I haven''t found > a way to get around this problem.. I was quite enthusiastic about > rails until now, but now I''m getting cold. If such an obvious thing is > so difficult to do, maybe it''s not the right framework to use.. I > don''t know.. > > On 2 Mar, 03:59, Ikari Shinji <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> > wrote: > > > Ci. wrote: > > > Hi everybody, > > > here is my problem. > > > > I have a Post model, a Tag model, and they are related to each other > > > by an has_and_belongs_to_many relationship. > > > > Now I run ./script/console: > > > > p=Post.new > > > p.title="Hello" > > > p.save > > > > t=Tag.new > > > t.name="tag1" > > > p.tags = [t] > > > > The result is that a Post record is created and saved, and then also a > > > Tag record is created and saved, together with a record in the join > > > table posts_tags. > > > The question is: why are the tag and the record in the join table > > > saved? Shouldn''t they wait for an explicit save? > > > To be more clear, why the last line ( p.tags=[t] ) triggers the > > > creation in the database of a record in the tags table and another in > > > the posts_tags table? Is there a way from stopping this until an > > > explicit save > > > occurs? > > > > I hope someone can answer my question, I''m quite a rails newbie so I > > > need help. Thanks. > > > I searched the rails apihttp://api.rubyonrails.org/andlook into the > > module ActiveRecord::Associations::ClassMethods > > And I found the following words that may be helpful > > > * Adding an object to a collection (has_many or > > has_and_belongs_to_many) automatically saves that object, except if the > > parent object (the owner of the collection) is not yet stored in the > > database. > > * If saving any of the objects being added to a collection (via push > > or similar) fails, then push returns false. > > * You can add an object to a collection without automatically saving > > it by using the collection.build method (documented below). > > * All unsaved (new_record? == true) members of the collection are > > automatically saved when the parent is saved. > > > Please Contact me ,i''m a newbie too... and wanna a friend > > MSN:ikari.shinji....-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org > > -- > > Posted viahttp://www.ruby-forum.com/.--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
On Mar 2, 5:44 pm, Jake Paul <dotj...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> According to the API docs Ikari posted above, you can add a tag to the > p model either by using the collection.build method:> or by not saving your p object before adding the tag: >These are not options in my application. I have posts and tags, and I have to associate existing tags to a post, on edit. So the tags already exist, and so does the post, because I''m editing an already saved post. What I''m trying to do is editing a post and the associated tag model in the same form, using a text field for the tag list, which then I convert to the correct tags to feed the model. But it doesn''t work as expected. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
In that case, if you have an existing post and an existing tag, and your habtm associations are set up correctly, if you have a collection_select in your form named post_tag_id and submit it along with rest of your params, then run @post.update_attributes!(params[:post]) in your controller, Rails handles the associations all by itself and will update the join table. The collection select will look something like: <%= form.collection_select(:post_tag_id, @tags, :id, :name, {}, {}) %> Note that you''ll need to create a @tags object in your edit action that contains all the tags you want as options. It sounds to me like your talking about categories, ie one per post from a set group, more than tags, which generally mean that a user can come up with as many tags as they''d like with any new post. If it is tags you want, though, then you might want to check out plugins such as Acts as Taggable. On Mar 2, 12:08 pm, "Ci." <cicci...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Mar 2, 5:44 pm, Jake Paul <dotj...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > According to the API docs Ikari posted above, you can add a tag to the > > p model either by using the collection.build method: > > or by not saving your p object before adding the tag: > > These are not options in my application. I have posts and tags, and I > have to > associate existing tags to a post, on edit. So the tags already exist, > and so does the post, > because I''m editing an already saved post. > What I''m trying to do is editing a post and the associated tag model > in the same form, > using a text field for the tag list, which then I convert to the > correct tags to feed the model. But > it doesn''t work as expected.--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Ci. wrote:> Hi everybody, > here is my problem. > > I have a Post model, a Tag model, and they are related to each other > by an has_and_belongs_to_many relationship. > > Now I run ./script/console: > > p=Post.new > p.title="Hello" > p.save > > t=Tag.new > t.name="tag1" > p.tags = [t] > > The result is that a Post record is created and saved, and then also a > Tag record is created and saved, together with a record in the join > table posts_tags. > The question is: why are the tag and the record in the join table > saved? Shouldn''t they wait for an explicit save? > To be more clear, why the last line ( p.tags=[t] ) triggers the > creation in the database of a record in the tags table and another in > the posts_tags table? Is there a way from stopping this until an > explicit save > occurs? > > I hope someone can answer my question, I''m quite a rails newbie so I > need help. Thanks.Er... I''ve got something useful,I''ll take it in an example first,I create two table Posts & Tags,and association table Posts_Tags,and habtm assciation in models then,script/console,one command followed by the data table>> p = Post.new=> #<Post:0x3477af4 @new_record=true, @attributes={"sth"=>nil}>>> p.save=> true>> t = Tag.new=> #<Tag:0x3460fc0 @new_record=true, @attributes={"sth"=>nil}>>> t.save=> true>> p.tags.send("load_target")=> []>> p.tags.target << t=> [#<Tag:0x3460fc0 @new_record=false, @errors=#<ActiveRecord::Errors:0x345eb30 @errors={}, @base=#<Tag:0x3460fc0 ...>>, @attributes={"id"=>1, "sth"=>nil}, @new_record_before_save=true>] and the data table ... mysql> select * from posts_tags; Empty set (0.01 sec) and the model ...>> y p.tags--- - &id001 !ruby/object:Tag attributes: id: 1 sth: errors: !ruby/object:ActiveRecord::Errors base: *id001 errors: {} new_record: false new_record_before_save: true => nil so , i got it ,i separate model association from data table[bad ENGLISH i know ... ] when you want to save the associations , following is the answer>> p.tags.send("insert_record",t)=> true and the data table ... mysql> select * from posts_tags; +----+---------+--------+ | id | post_id | tag_id | +----+---------+--------+ | 1 | 1 | 1 | +----+---------+--------+ 1 row in set (0.00 sec) SO , I GOT IT, didn''t I? hehe , I read the source code and hope this will help you too. Please give me your MSN,I wanna a coder friend[bad english,i know...] PS, transaction block is recommended from the source code,in this example... p.transaction do # Er ... end ^^ -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Ikari Shinji wrote:> Er... I''ve got something useful,I''ll take it in an example > > first,I create two table Posts & Tags,and association table > Posts_Tags,and habtm assciation in models > > then,script/console > >>> p = Post.new > => #<Post:0x3477af4 @new_record=true, @attributes={"sth"=>nil}> >>> p.save > => true >>> t = Tag.new > => #<Tag:0x3460fc0 @new_record=true, @attributes={"sth"=>nil}> >>> t.save > => true >>> p.tags.send("load_target") > => [] >>> p.tags.target << t > => [#<Tag:0x3460fc0 @new_record=false, > @errors=#<ActiveRecord::Errors:0x345eb30 @errors={}, > @base=#<Tag:0x3460fc0 ...>>, @attributes={"id"=>1, "sth"=>nil}, > @new_record_before_save=true>] > > and the data table ... > > mysql> select * from posts_tags; > Empty set (0.01 sec) > > and the model ... > >>> y p.tags > --- > - &id001 !ruby/object:Tag > attributes: > id: 1 > sth: > errors: !ruby/object:ActiveRecord::Errors > base: *id001 > errors: {} > > new_record: false > new_record_before_save: true > => nil > > so , i got it ,i separate model association from data table[bad ENGLISH > i know ... ] > > when you want to save the associations , following is the answer > >>> p.tags.send("insert_record",t) > => true > > and the data table ... > mysql> select * from posts_tags; > +----+---------+--------+ > | id | post_id | tag_id | > +----+---------+--------+ > | 1 | 1 | 1 | > +----+---------+--------+ > 1 row in set (0.00 sec) > > SO , I GOT IT, didn''t I? > > hehe , I read the source code and hope this will help you too. > Please give me your MSN,I wanna a coder friend[bad english,i know...] > > PS, transaction block is recommended from the source code,in this > example... > > p.transaction do > # Er ... > end > > ^^"one command followed by the data table" has something wrong ... apologize... i fotgot reload the Post Model so you could catch errors on p.tags[0].errors attributes>> p.reload=> #<Post:0x3477af4 @new_record=false, @tags=nil, @errors=#<ActiveRecord::Errors:0x346bee8 @errors={}, @base=#<Post:0x3477af4 ...>>, @attributes={"id"=>"1", "sth"=>nil}, @new_record_before_save=true>>> y p.tags--- - !ruby/object:Tag attributes: tag_id: "1" post_id: "1" id: "1" sth: readonly: true => nil it''s OK -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Thank you for the answer. Really, I don''t know if this can be useful in my application.. there seem to be low level calls.. I don''t know, anyway I''ll play with it and see if something comes out. I''ll give you my ICQ (I don''t have MSN) if you email me, my email address is ciccio.a [AT] gmail [DOT] com. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
@Ci -- this sounds a lot like acts_as_taggable. You might want to look into that plugin so you can go on to other interesting code. Back on topic, the habtm call creates an association proxy for your Post class. If you ask for an assignment on that proxy, it assumes that you are giving it the new set of associations to be managed. That''s why it''s saved instantly. Similarly, you can append the collection. You just need to take advantage of what Rails is giving you. From your description I assume that you are taking the contents of the text field, splitting on whitespaces, and then using each item in the collection as a tag. Is that correct? So maybe a loop like this will work: tag_texts = params[:tags].split /\s+/ requested_tags = tag_texts.collect do |tag_text| Tag.find_by_text(tag_text) || Tag.create(:text=>tag_text) end @post.tags = requested_tags tag_texts.collect is building up an array of Tag instances by finding the Tag, if it exists, or creating one. You can then pass that array to the tags proxy on your Post and it will take care of the rest. The advantage of this (why Rails is doing instant saves in fact!) is that you don''t have to worry about whether or not the collection already contained the tag -- Rails manages it for you. HTH, AndyV On Mar 2, 12:08 pm, "Ci." <cicci...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Mar 2, 5:44 pm, Jake Paul <dotj...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > According to the API docs Ikari posted above, you can add a tag to the > > p model either by using the collection.build method: > > or by not saving your p object before adding the tag: > > These are not options in my application. I have posts and tags, and I > have to > associate existing tags to a post, on edit. So the tags already exist, > and so does the post, > because I''m editing an already saved post. > What I''m trying to do is editing a post and the associated tag model > in the same form, > using a text field for the tag list, which then I convert to the > correct tags to feed the model. But > it doesn''t work as expected.--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Thank you for helping me. I finally find quite a clean way to solve my problem. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---