I was at a Seattle.rb meeting recently. A demonstration of Rails was being held. The guy was showing off a cemetary website. He added acts_as_list and a position to each gravestone. When he attempted to add the functionality of moving the position of a gravestone up or down in the list, he ran into some problems. At first (this is from my probably wrong memory), he tried using #move_heigher. So, a cemetary that was at the end of the list (#10) would move up to #9. But then we ran into some key restraints, namely, that there were now two gravestones at position #9. So we tried to move the gravestone at #9 up to #10 and the #9 down to #10. But each time #save was called, that key constraint problem occured again. So, what was the correct solution here? What does acts_as_list actually give you? Thanks, Joe
On 13 Apr 2005, at 19:02, Joe Van Dyk wrote:> At first (this is from my probably wrong memory), he tried using > #move_heigher. So, a cemetary that was at the end of the list (#10) > would move up to #9. But then we ran into some key restraints, > namely, that there were now two gravestones at position #9.Maybe my SQL isn''t good enough, but I don''t think there''s a sane (portable) way to get around this. I ended up removing the constraints on my ordered table, and let AR keep things in order. For MySQL, you could turn constraints off at the start of the move_higher transaction, and turn them on again at the end of the transaction. I decided that this wasn''t worth the hassle for me: in my use case, the position field isn''t exposed, so it doesn''t much matter if something breaks slightly. Cheers, Alisdair
I use a date column as my position. I figure there''s a very slim chance of two items being entered at *exactly* the same time, so this seems to work out well. Course, this won''t help with acts_as_list, however. On 4/13/05, Alisdair McDiarmid <alisdair-funMMXNoeIe8UoyrqSfgCw@public.gmane.org> wrote:> On 13 Apr 2005, at 19:02, Joe Van Dyk wrote: > > > At first (this is from my probably wrong memory), he tried using > > #move_heigher. So, a cemetary that was at the end of the list (#10) > > would move up to #9. But then we ran into some key restraints, > > namely, that there were now two gravestones at position #9. > > Maybe my SQL isn''t good enough, but I don''t think there''s a sane > (portable) way to get around this. I ended up removing the constraints > on my ordered table, and let AR keep things in order. > > For MySQL, you could turn constraints off at the start of the > move_higher transaction, and turn them on again at the end of the > transaction. I decided that this wasn''t worth the hassle for me: in my > use case, the position field isn''t exposed, so it doesn''t much matter > if something breaks slightly. > > Cheers, > Alisdair > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- rick http://techno-weenie.net
Alisdair McDiarmid wrote:> On 13 Apr 2005, at 19:02, Joe Van Dyk wrote: > >> At first (this is from my probably wrong memory), he tried using >> #move_heigher. So, a cemetary that was at the end of the list (#10) >> would move up to #9. But then we ran into some key restraints, >> namely, that there were now two gravestones at position #9. > > > Maybe my SQL isn''t good enough, but I don''t think there''s a sane > (portable) way to get around this. I ended up removing the constraints > on my ordered table, and let AR keep things in order. > > For MySQL, you could turn constraints off at the start of the > move_higher transaction, and turn them on again at the end of the > transaction. I decided that this wasn''t worth the hassle for me: in my > use case, the position field isn''t exposed, so it doesn''t much matter if > something breaks slightly.PostgreSQL can defer constraints checking to transaction commit, so that''d work.. if it wasn''t limited to foreign key checks only. Otherwise, your choices are to disable to the UNIQUE constraint or to patch ActiveRecord::Acts::List to safely manipulate the list positions. For example, list a -> b with positions 1, 2. unsafe a b b.move_higher a.position += 1 2 2 XXX b.position -= 1 2 1 safe a b b.move_higher old = b.position 1 2 b.position = nil 1 nil a.position += 1 2 nil b.position = old-1 2 1 jeremy
I was able to use it successfully with mysql. The trick for me was being sure to put "order" in the has_many. Here was a sample of my code: <code> class Quiz < ActiveRecord::Base has_many :questions, :order => "position" end class Question < ActiveRecord::Base belongs_to :quiz acts_as_list :scope => :quiz end . . . # now you can do things like quiz.questions[1].move_lower quiz.questions.first.move_to_bottom </code>
I take it there was no constraint on uniqueness on the ''position'' column? In Postgres, how does one disable the uniqueness constraint temporarily? Thanks, Joe On 4/13/05, Philip Gatt <gattster-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I was able to use it successfully with mysql. The trick for me was > being sure to put "order" in the has_many. > > Here was a sample of my code: > > <code> > class Quiz < ActiveRecord::Base > has_many :questions, :order => "position" > end > > class Question < ActiveRecord::Base > belongs_to :quiz > acts_as_list :scope => :quiz > end > > . . . > # now you can do things like > quiz.questions[1].move_lower > quiz.questions.first.move_to_bottom > </code> > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >