I''ve got a table of events, and each event has a boolean attribute is_ten_event. On each row of the table is a chekbox to edit the value of is_ten_event, so that multiple rows can be edited with one submit. In order to allow boxes to be un-checked as well, the logic in the controller works like this get array of events from checkboxes that are ticked. make all events.is_ten_event = false make all events in array . is_ten_event = true When I first check the checkbox and submit, everything works fine, the attribute is updated in the database and the table view reflects the changes. If I then submit again, with the same values still checked the values I set the last time get set to false. The view code looks like this : check_box_tag "is_ten_event_ids[]", event.id, event.is_ten_event The controller is like this : def multi_params_edit @events = Event.find( params[:is_ten_event_ids] ) logger.debug("MULTI PARAMS EDIT : " + @events.length.to_s) unless @events.empty? Event.transaction do Event.update_all(:is_ten_event => false) @events.each do |e| logger.debug("trying to make event is_ten_event = true") e.update_attribute(:is_ten_event, true) end end end redirect_to (:action =>:index) end Here''s the log output from the first submit (when it works) Started POST "/admin/events/events/multi_params_edit" for 127.0.0.1 at Sun Aug 14 19:37:42 +0100 2011 Processing by Admin::Events::EventsController#multi_params_edit as HTML Parameters: {"commit"=>"save changes (not functional)", "authenticity_token"=>"3MJ8aUhRWkrsOTLzkcLup8s7wrQH387H7uJeeKEU9Ss=", "utf8"=>"✓", "is_ten_event_ids"=>["5", "12", "20"]} User Load (0.2ms) SELECT "users".* FROM "users" WHERE ("users"."id" 3) LIMIT 1 AREL (0.4ms) UPDATE "users" SET "last_access" = ''2011-08-14 18:37:42.858005'', "updated_at" = ''2011-08-14 18:37:42.858858'' WHERE ("users"."id" = 3) Event Load (0.6ms) SELECT "events".* FROM "events" WHERE ("events"."id" IN (5, 12, 20)) MULTI PARAMS EDIT : 3 AREL (1.9ms) UPDATE "events" SET "is_ten_event" = ''f'' trying to make event is_ten_event = true AREL (0.2ms) UPDATE "events" SET "is_ten_event" = ''t'', "updated_at" ''2011-08-14 18:37:42.913564'' WHERE ("events"."id" = 5) trying to make event is_ten_event = true AREL (0.1ms) UPDATE "events" SET "is_ten_event" = ''t'', "updated_at" ''2011-08-14 18:37:42.916311'' WHERE ("events"."id" = 12) trying to make event is_ten_event = true AREL (0.1ms) UPDATE "events" SET "is_ten_event" = ''t'', "updated_at" ''2011-08-14 18:37:42.918503'' WHERE ("events"."id" = 20) Redirected to http://0.0.0.0:3000/admin/events/events And here''s the log output from the second submit (when it doesn''t work) Started POST "/admin/events/events/multi_params_edit" for 127.0.0.1 at Sun Aug 14 19:37:49 +0100 2011 Processing by Admin::Events::EventsController#multi_params_edit as HTML Parameters: {"commit"=>"save changes (not functional)", "authenticity_token"=>"3MJ8aUhRWkrsOTLzkcLup8s7wrQH387H7uJeeKEU9Ss=", "utf8"=>"✓", "is_ten_event_ids"=>["5", "12", "20"]} User Load (0.3ms) SELECT "users".* FROM "users" WHERE ("users"."id" 3) LIMIT 1 AREL (0.4ms) UPDATE "users" SET "updated_at" = ''2011-08-14 18:37:50.369619'', "last_access" = ''2011-08-14 18:37:50.368912'' WHERE ("users"."id" = 3) Event Load (0.6ms) SELECT "events".* FROM "events" WHERE ("events"."id" IN (5, 12, 20)) MULTI PARAMS EDIT : 3 AREL (1.9ms) UPDATE "events" SET "is_ten_event" = ''f'' trying to make event is_ten_event = true trying to make event is_ten_event = true trying to make event is_ten_event = true Redirected to http://0.0.0.0:3000/admin/events/events As you can see, in both cases, the 3 event ids which are checked get passed through, and the length of the @events array is 3. After all events are set to false, the first log staement shows the block being executed, and the database being updated. The second log statement shows that although the block was run (from the printout "trying to make event is_ten_event = true") the update_attribute call didn''t do anything! CAn anyone tell me why?? it seems very simple this, so probably doing something silly. What is also odd however is that I wrapped the whole thing in a Transaction, which should ensure that if the update_attribute didn''t work, the set all events to is_ten_event = false call should be rolled back, but this doesn''t happen either! I''m losing faith in transaction as a method, and update_attribute. I''m somewhat losing faith in reality! Can anyone please help!?? -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@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 Aug 14, 2011, at 2:58 PM, Michael Baldock wrote:> I''ve got a table of events, and each event has a boolean attribute > is_ten_event. > > On each row of the table is a chekbox to edit the value of > is_ten_event, > so that multiple rows can be edited with one submit. > > In order to allow boxes to be un-checked as well, the logic in the > controller works like this > > get array of events from checkboxes that are ticked. > make all events.is_ten_event = false > make all events in array . is_ten_event = true > > When I first check the checkbox and submit, everything works fine, the > attribute is updated in the database and the table view reflects the > changes. > If I then submit again, with the same values still checked the > values I > set the last time get set to false. > > The view code looks like this : > > check_box_tag "is_ten_event_ids[]", event.id, event.is_ten_event > > The controller is like this : > > def multi_params_edit > > @events = Event.find( params[:is_ten_event_ids] ) > logger.debug("MULTI PARAMS EDIT : " + @events.length.to_s) > > > unless @events.empty? > > Event.transaction do > Event.update_all(:is_ten_event => false) > @events.each do |e| > logger.debug("trying to make event is_ten_event = true") > e.update_attribute(:is_ten_event, true) > end > end > end > > redirect_to (:action =>:index) > > end > > > Here''s the log output from the first submit (when it works) > > Started POST "/admin/events/events/multi_params_edit" for 127.0.0.1 at > Sun Aug 14 19:37:42 +0100 2011 > Processing by Admin::Events::EventsController#multi_params_edit as > HTML > Parameters: {"commit"=>"save changes (not functional)", > "authenticity_token"=>"3MJ8aUhRWkrsOTLzkcLup8s7wrQH387H7uJeeKEU9Ss=", > "utf8"=>"✓", "is_ten_event_ids"=>["5", "12", "20"]} > User Load (0.2ms) SELECT "users".* FROM "users" WHERE > ("users"."id" > 3) LIMIT 1 > AREL (0.4ms) UPDATE "users" SET "last_access" = ''2011-08-14 > 18:37:42.858005'', "updated_at" = ''2011-08-14 18:37:42.858858'' WHERE > ("users"."id" = 3) > Event Load (0.6ms) SELECT "events".* FROM "events" WHERE > ("events"."id" IN (5, 12, 20)) > MULTI PARAMS EDIT : 3 > AREL (1.9ms) UPDATE "events" SET "is_ten_event" = ''f'' > trying to make event is_ten_event = true > AREL (0.2ms) UPDATE "events" SET "is_ten_event" = ''t'', > "updated_at" > ''2011-08-14 18:37:42.913564'' WHERE ("events"."id" = 5) > trying to make event is_ten_event = true > AREL (0.1ms) UPDATE "events" SET "is_ten_event" = ''t'', > "updated_at" > ''2011-08-14 18:37:42.916311'' WHERE ("events"."id" = 12) > trying to make event is_ten_event = true > AREL (0.1ms) UPDATE "events" SET "is_ten_event" = ''t'', > "updated_at" > ''2011-08-14 18:37:42.918503'' WHERE ("events"."id" = 20) > Redirected to http://0.0.0.0:3000/admin/events/events > > > And here''s the log output from the second submit (when it doesn''t > work) > > Started POST "/admin/events/events/multi_params_edit" for 127.0.0.1 at > Sun Aug 14 19:37:49 +0100 2011 > Processing by Admin::Events::EventsController#multi_params_edit as > HTML > Parameters: {"commit"=>"save changes (not functional)", > "authenticity_token"=>"3MJ8aUhRWkrsOTLzkcLup8s7wrQH387H7uJeeKEU9Ss=", > "utf8"=>"✓", "is_ten_event_ids"=>["5", "12", "20"]} > User Load (0.3ms) SELECT "users".* FROM "users" WHERE > ("users"."id" > 3) LIMIT 1 > AREL (0.4ms) UPDATE "users" SET "updated_at" = ''2011-08-14 > 18:37:50.369619'', "last_access" = ''2011-08-14 18:37:50.368912'' WHERE > ("users"."id" = 3) > Event Load (0.6ms) SELECT "events".* FROM "events" WHERE > ("events"."id" IN (5, 12, 20)) > MULTI PARAMS EDIT : 3 > AREL (1.9ms) UPDATE "events" SET "is_ten_event" = ''f'' > trying to make event is_ten_event = true > trying to make event is_ten_event = true > trying to make event is_ten_event = true > Redirected to http://0.0.0.0:3000/admin/events/events > > > As you can see, in both cases, the 3 event ids which are checked get > passed through, and the length of the @events array is 3. After all > events are set to false, the first log staement shows the block being > executed, and the database being updated. The second log statement > shows > that although the block was run (from the printout "trying to make > event > is_ten_event = true") the update_attribute call didn''t do anything! > > CAn anyone tell me why?? it seems very simple this, so probably doing > something silly. > > What is also odd however is that I wrapped the whole thing in a > Transaction, which should ensure that if the update_attribute didn''t > work, the set all events to is_ten_event = false call should be rolled > back, but this doesn''t happen either! > > I''m losing faith in transaction as a method, and update_attribute. > I''m somewhat losing faith in reality! > > Can anyone please help!??Try doing it without any special effort in the controller. If you view source on a form page that Rails has generated with the form builder method check_box, you''ll see that there''s a hidden element generated before the checkbox, with the same name as the checkbox, and with the value=0. That takes care of your "un-checked checkboxes aren''t submitted by the browser" problem for you, automagically. Your system (unless you are using hand-coded checkboxes) is redundant, and probably confusing to update_attributes. Walter -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@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.
Walter, thanks for helping, "Try doing it without any special effort in the controller." Not sure what you mean I should do, I understand what you''re saying, but I''m not sure what the ''normal'' / simple way to do this is. This is what I''ve got in the controller after trying to simplify like you said: def multi_params_edit @events = Event.find( params[:is_ten_event_ids] ) logger.debug("MULTI PARAMS EDIT : " + @events.length.to_s) @events.each do |e| logger.debug("trying to make event is_ten_event = true") e.update_attribute(:is_ten_event, true) end redirect_to (:action =>:index) end but this does what I was trying to avoid, and when I uncheck the box and submit, the attribute is not changed. the check returns! Could you possibly explain how I should do this in a little more detail please. Thanks -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Aug 14, 2011, at 5:31 PM, Michael Baldock wrote:> Walter, thanks for helping, > > > "Try doing it without any special effort in the controller." > > Not sure what you mean I should do, I understand what you''re saying, > but > I''m not sure what the ''normal'' / simple way to do this is. > > This is what I''ve got in the controller after trying to simplify like > you said: > > def multi_params_edit > > @events = Event.find( params[:is_ten_event_ids] ) > logger.debug("MULTI PARAMS EDIT : " + @events.length.to_s) > > @events.each do |e| > logger.debug("trying to make event is_ten_event = true") > e.update_attribute(:is_ten_event, true) > end > > redirect_to (:action =>:index) > > end > > > but this does what I was trying to avoid, and when I uncheck the box > and > submit, the attribute is not changed. the check returns! Could you > possibly explain how I should do this in a little more detail please.It sounds like you''re inside a different controller than the EventsController. Is that true? Could you set this up with nested attributes? class Foo has_many :events accepts_nested_attributes_for :events end class Event belongs_to :foo end #FooController def update @foo = Foo.find(params[:id]) if @foo.update_attributes(params[:foo]) redirect_to @foo, :notice => ''Yay'' else render :action => :edit end end foos/edit.html.erb <%= form_for @foo do |f| %> ... regular Foo fields here ... <%= f.fields_for :events do |builder| %> <%= render "event_fields", :f => builder %> <% end %> ... rest of the form, including the submit ... <% end %> foos/_event_fields.html.erb ... any other Event fields ... <%= f.check_box :is_ten_event %> Now Foo can have as many Events as it needs, and each Event can have an is_ten_event checkbox with the magical un-check ability, and the controller can take care of everything in one submit, with no extra effort. Unless I''m completely missing the point of your domain model, this should Just Work™. Walter -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@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 Aug 14, 7:58 pm, Michael Baldock <li...-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote:> I''ve got a table of events, and each event has a boolean attribute > is_ten_event. > > On each row of the table is a chekbox to edit the value of is_ten_event, > so that multiple rows can be edited with one submit. > > In order to allow boxes to be un-checked as well, the logic in the > controller works like this > > get array of events from checkboxes that are ticked. > make all events.is_ten_event = false > make all events in array . is_ten_event = true > > When I first check the checkbox and submit, everything works fine, the > attribute is updated in the database and the table view reflects the > changes. > If I then submit again, with the same values still checked the values I > set the last time get set to false.The problem is rails'' change tracking. When you save a record, active record checks whether there are actually any changed attributes and saves those. You''ve loaded your events from the database, which have your flag set to true. Then you call update_all which changes everything to false in the database, but doesn''t update any objects that already exist in memory, so when you call update attribute, rails thinks you are setting to true something that is already true and doesn''t do anything. Fred> > The view code looks like this : > > check_box_tag "is_ten_event_ids[]", event.id, event.is_ten_event > > The controller is like this : > > def multi_params_edit > > @events = Event.find( params[:is_ten_event_ids] ) > logger.debug("MULTI PARAMS EDIT : " + @events.length.to_s) > > unless @events.empty? > > Event.transaction do > Event.update_all(:is_ten_event => false) > @events.each do |e| > logger.debug("trying to make event is_ten_event = true") > e.update_attribute(:is_ten_event, true) > end > end > end > > redirect_to (:action =>:index) > > end > > Here''s the log output from the first submit (when it works) > > Started POST "/admin/events/events/multi_params_edit" for 127.0.0.1 at > Sun Aug 14 19:37:42 +0100 2011 > Processing by Admin::Events::EventsController#multi_params_edit as > HTML > Parameters: {"commit"=>"save changes (not functional)", > "authenticity_token"=>"3MJ8aUhRWkrsOTLzkcLup8s7wrQH387H7uJeeKEU9Ss=", > "utf8"=>"✓", "is_ten_event_ids"=>["5", "12", "20"]} > User Load (0.2ms) SELECT "users".* FROM "users" WHERE ("users"."id" > 3) LIMIT 1 > AREL (0.4ms) UPDATE "users" SET "last_access" = ''2011-08-14 > 18:37:42.858005'', "updated_at" = ''2011-08-14 18:37:42.858858'' WHERE > ("users"."id" = 3) > Event Load (0.6ms) SELECT "events".* FROM "events" WHERE > ("events"."id" IN (5, 12, 20)) > MULTI PARAMS EDIT : 3 > AREL (1.9ms) UPDATE "events" SET "is_ten_event" = ''f'' > trying to make event is_ten_event = true > AREL (0.2ms) UPDATE "events" SET "is_ten_event" = ''t'', "updated_at" > ''2011-08-14 18:37:42.913564'' WHERE ("events"."id" = 5) > trying to make event is_ten_event = true > AREL (0.1ms) UPDATE "events" SET "is_ten_event" = ''t'', "updated_at" > ''2011-08-14 18:37:42.916311'' WHERE ("events"."id" = 12) > trying to make event is_ten_event = true > AREL (0.1ms) UPDATE "events" SET "is_ten_event" = ''t'', "updated_at" > ''2011-08-14 18:37:42.918503'' WHERE ("events"."id" = 20) > Redirected tohttp://0.0.0.0:3000/admin/events/events > > And here''s the log output from the second submit (when it doesn''t work) > > Started POST "/admin/events/events/multi_params_edit" for 127.0.0.1 at > Sun Aug 14 19:37:49 +0100 2011 > Processing by Admin::Events::EventsController#multi_params_edit as > HTML > Parameters: {"commit"=>"save changes (not functional)", > "authenticity_token"=>"3MJ8aUhRWkrsOTLzkcLup8s7wrQH387H7uJeeKEU9Ss=", > "utf8"=>"✓", "is_ten_event_ids"=>["5", "12", "20"]} > User Load (0.3ms) SELECT "users".* FROM "users" WHERE ("users"."id" > 3) LIMIT 1 > AREL (0.4ms) UPDATE "users" SET "updated_at" = ''2011-08-14 > 18:37:50.369619'', "last_access" = ''2011-08-14 18:37:50.368912'' WHERE > ("users"."id" = 3) > Event Load (0.6ms) SELECT "events".* FROM "events" WHERE > ("events"."id" IN (5, 12, 20)) > MULTI PARAMS EDIT : 3 > AREL (1.9ms) UPDATE "events" SET "is_ten_event" = ''f'' > trying to make event is_ten_event = true > trying to make event is_ten_event = true > trying to make event is_ten_event = true > Redirected tohttp://0.0.0.0:3000/admin/events/events > > As you can see, in both cases, the 3 event ids which are checked get > passed through, and the length of the @events array is 3. After all > events are set to false, the first log staement shows the block being > executed, and the database being updated. The second log statement shows > that although the block was run (from the printout "trying to make event > is_ten_event = true") the update_attribute call didn''t do anything! > > CAn anyone tell me why?? it seems very simple this, so probably doing > something silly. > > What is also odd however is that I wrapped the whole thing in a > Transaction, which should ensure that if the update_attribute didn''t > work, the set all events to is_ten_event = false call should be rolled > back, but this doesn''t happen either! > > I''m losing faith in transaction as a method, and update_attribute. > I''m somewhat losing faith in reality! > > Can anyone please help!?? > > -- > 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@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.
@Walter Actually the form being submitted is going through EventsController, the table of events is just the events/index, and I''ve made a new route called events/multi_params_edit, which is where the form submits to. So the EventsController is trying to update lots of events, not an associated model. Thanks for the advice though, it''s actually helped somewhere else! @Fred - Ok that makes sense, what would be the correct way to do this then? Can I somehow set all to false all events, except those passed in as params? Or can I somehow force it to set the value to true even though it thinks it has done it already? Thanks for the help -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.