Greg Willits
2008-May-13 02:09 UTC
Stumped by Ajax + Session + Saving Model + Private Method
Got stumped by this one... Had a working form_remote_tag that used rjs to toggle between a static view of the data and a form with inputs. Saving that form updated an ActiveRecord model. Then I realized I needed to move the actions I was using to view/edit/ save this form into the private section of the controller (calling them directly via URL not a good thing). Now the Saving doesn''t actually save anything. No crashes, but the data isn''t updated. I suspect it is because I store the ID of the object in a session, and somehow the Ajax invocation of the action fails to restore the session -- but why the method being private vs public would matter to that, I don''t know. Or maybe it is something else. The saving method looks like this: def emergency_contact_save @client = Client.find(session[:selected_client_id]) @client.emergFirstName = params[:emergFirstName] ..... more params ..... @client.save respond_to do |request_format| request_format.js end end works perfect if it is a public method, doesn''t work if it is private. Not sure what other code I''d need to show. Any ideas?? -- gw --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Nicholas Henry
2008-May-13 02:46 UTC
Re: Stumped by Ajax + Session + Saving Model + Private Method
If emergency_contact_save is the method you are calling from your form and you moved it from public to private you should know then you cannot call a private method via a request. Or is emergency_contact_save called from def save which is public? Cheers, Nicholas On May 12, 10:09 pm, Greg Willits <li...-0Bv1hcaDFPRk211Z5VL+QA@public.gmane.org> wrote:> Got stumped by this one... Had a working form_remote_tag that used > rjs to toggle between a static view of the data and a form with > inputs. Saving that form updated an ActiveRecord model. > > Then I realized I needed to move the actions I was using to view/edit/ > save this form into the private section of the controller (calling > them directly via URL not a good thing). > > Now the Saving doesn''t actually save anything. No crashes, but the > data isn''t updated. I suspect it is because I store the ID of the > object in a session, and somehow the Ajax invocation of the action > fails to restore the session -- but why the method being private vs > public would matter to that, I don''t know. Or maybe it is something > else. > > The saving method looks like this: > > def emergency_contact_save > > @client = Client.find(session[:selected_client_id]) > -1IhipSbaZsSyE9eC/SvJWdO4PUGVA46s@public.gmane.org = params[:emergFirstName] > ..... more params ..... > -cLsJFYQ6yVffhZSSa7DgLw@public.gmane.org > respond_to do |request_format| > request_format.js > end > > end > > works perfect if it is a public method, doesn''t work if it is private. > > Not sure what other code I''d need to show. > > Any ideas?? > > -- gw--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Greg Willits
2008-May-13 03:07 UTC
Re: Stumped by Ajax + Session + Saving Model + Private Method
Yeah I was just about to post that after thinking about this, I realized the Ajax request is still making a call to a public URL that Rails is going to map to an action. The screen gymnastics continued to work because Rails would still find the .rjs file and run them. OK, so here''s the real problem -- if I put it all back as public actions, then using the web UI works all good. However, if I simply enter a URL for that Ajax into the browser I get a big messy javascript upchuck on the page, _and_ it wipes out the data in that model that is supposed to be updated because there is no data. Clearly, calling this URL directly is not good. Submitting no data (i.e. clearing what existed) is a valid submission, so I can''t just add some code that says an submission with all fields as empty is invalid -- it''s not invalid. So, what''s the pattern for ensuring that calls to controller actions are called by their proper Ajax context? That and I have to figure out why the Javascript upchuck? -- gw On May 12, 2008, at 7:46 PM, Nicholas Henry wrote:> > If emergency_contact_save is the method you are calling from your form > and you moved it from public to private you should know then you > cannot call a private method via a request. Or is > emergency_contact_save called from def save which is public? > > Cheers, > Nicholas > > On May 12, 10:09 pm, Greg Willits <li...-0Bv1hcaDFPRk211Z5VL+QA@public.gmane.org> wrote: >> Got stumped by this one... Had a working form_remote_tag that used >> rjs to toggle between a static view of the data and a form with >> inputs. Saving that form updated an ActiveRecord model. >> >> Then I realized I needed to move the actions I was using to view/ >> edit/ >> save this form into the private section of the controller (calling >> them directly via URL not a good thing). >> >> Now the Saving doesn''t actually save anything. No crashes, but the >> data isn''t updated. I suspect it is because I store the ID of the >> object in a session, and somehow the Ajax invocation of the action >> fails to restore the session -- but why the method being private vs >> public would matter to that, I don''t know. Or maybe it is something >> else. >> >> The saving method looks like this: >> >> def emergency_contact_save >> >> @client = Client.find(session[:selected_client_id]) >> @client.emergFirstName = params[:emergFirstName] >> ..... more params ..... >> @client.save >> respond_to do |request_format| >> request_format.js >> end >> >> end >> >> works perfect if it is a public method, doesn''t work if it is >> private. >>--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Nicholas Henry
2008-May-13 03:24 UTC
Re: Stumped by Ajax + Session + Saving Model + Private Method
I think it''s your implementation of the form/params hash that could improve and solve your issue here: --- controller --- def emergency_contact_save @client = Client.find(session[:selected_client_id]) @client.attributes = params[:client] # instead of setting them individually @client.save respond_to do |request_format| request_format.js end end --- view --- <% remote_form_for @client do %> ...fields..... <%end %> This way if the params[:client] has is nil none of the attributes will be touched. HTH, Nicholas On May 12, 11:07 pm, Greg Willits <li...-0Bv1hcaDFPRk211Z5VL+QA@public.gmane.org> wrote:> Yeah I was just about to post that after thinking about this, I > realized the Ajax request is still making a call to a public URL that > Rails is going to map to an action. The screen gymnastics continued > to work because Rails would still find the .rjs file and run them. > > OK, so here''s the real problem -- if I put it all back as public > actions, then using the web UI works all good. However, if I simply > enter a URL for that Ajax into the browser I get a big messy > javascript upchuck on the page, _and_ it wipes out the data in that > model that is supposed to be updated because there is no data. > Clearly, calling this URL directly is not good. > > Submitting no data (i.e. clearing what existed) is a valid > submission, so I can''t just add some code that says an submission > with all fields as empty is invalid -- it''s not invalid. > > So, what''s the pattern for ensuring that calls to controller actions > are called by their proper Ajax context? That and I have to figure > out why the Javascript upchuck? > > -- gw > > On May 12, 2008, at 7:46 PM, Nicholas Henry wrote: > > > > > If emergency_contact_save is the method you are calling from your form > > and you moved it from public to private you should know then you > > cannot call a private method via a request. Or is > > emergency_contact_save called from def save which is public? > > > Cheers, > > Nicholas > > > On May 12, 10:09 pm, Greg Willits <li...-0Bv1hcaDFPRk211Z5VL+QA@public.gmane.org> wrote: > >> Got stumped by this one... Had a working form_remote_tag that used > >> rjs to toggle between a static view of the data and a form with > >> inputs. Saving that form updated an ActiveRecord model. > > >> Then I realized I needed to move the actions I was using to view/ > >> edit/ > >> save this form into the private section of the controller (calling > >> them directly via URL not a good thing). > > >> Now the Saving doesn''t actually save anything. No crashes, but the > >> data isn''t updated. I suspect it is because I store the ID of the > >> object in a session, and somehow the Ajax invocation of the action > >> fails to restore the session -- but why the method being private vs > >> public would matter to that, I don''t know. Or maybe it is something > >> else. > > >> The saving method looks like this: > > >> def emergency_contact_save > > >> @client = Client.find(session[:selected_client_id]) > >> -1IhipSbaZsSyE9eC/SvJWdO4PUGVA46s@public.gmane.org = params[:emergFirstName] > >> ..... more params ..... > >> -cLsJFYQ6yVffhZSSa7DgLw@public.gmane.org > >> respond_to do |request_format| > >> request_format.js > >> end > > >> end > > >> works perfect if it is a public method, doesn''t work if it is > >> private.--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Greg Willits
2008-May-13 03:51 UTC
Re: Stumped by Ajax + Session + Saving Model + Private Method
On May 12, 2008, at 8:24 PM, Nicholas Henry wrote:> I think it''s your implementation of the form/params hash that could > improve and solve your issue here:Nah, that doesn''t matter. How the model is poulated isn''t relevant. I''ve removed the model altogther to better understand what Ajax and Rails are doing here, and somehow, Rails is still trying to call the RJS template even when the request is not XHR. So, I now have this: def emergency_contact_save if request.xhr? .... logger step comfirms an XHR request .... respond_to do |request_format| request_format.js end else .... logger step comfirms a Non-XHR request .... end end And, I have a file emergency_contact_save.rjs All works fine when using the web UI. When I use a direct URL /{controller}/emergency_contact_save I still get a javascript error which seems to come from Rails trying to run the emergency_contact_save.rjs file. If I remove the emergency_contact_save.rjs file and again try the URL /{controller}/emergency_contact_save I get a Rails error saying there is no rjs file. Now, that makes no sense to me at all that Rails should still be trying to find the rjs file at this point. Since that testing, I''ve restarted Rails and that seems to have changed a few things. Then I ended up building up to this code (added redirect): def emergency_contact_save if request.xhr? .... logger step comfirms an XHR request .... respond_to do |request_format| request_format.js end else .... logger step comfirms a Non-XHR request .... redirect_to :action => ''...the basic view of the page...'' end end That combination of xhr? and the redirect seems to be the cure. Now, maybe I need to do some refactoring to allow a legit POST, but for now this seems to take care of the problem of how to handle Ajax vs non-Ajax calls. Thanks for bouncing some ideas, Nicholas. -- gw --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Nicholas Henry
2008-May-13 04:07 UTC
Re: Stumped by Ajax + Session + Saving Model + Private Method
You could also do something like this at the top of your controller: verify :only => ''emergency_contact_save'', :xhr => true. That would be nicer than having the conditional statement in the method Nicholas On May 12, 11:51 pm, Greg Willits <li...-0Bv1hcaDFPRk211Z5VL+QA@public.gmane.org> wrote:> On May 12, 2008, at 8:24 PM, Nicholas Henry wrote: > > > I think it''s your implementation of the form/params hash that could > > improve and solve your issue here: > > Nah, that doesn''t matter. How the model is poulated isn''t relevant. > I''ve removed the model altogther to better understand what Ajax and > Rails are doing here, and somehow, Rails is still trying to call the > RJS template even when the request is not XHR. > > So, I now have this: > > def emergency_contact_save > > if request.xhr? > .... logger step comfirms an XHR request .... > > respond_to do |request_format| > request_format.js > end > else > .... logger step comfirms a Non-XHR request .... > end > > end > > And, I have a file emergency_contact_save.rjs > > All works fine when using the web UI. > > When I use a direct URL /{controller}/emergency_contact_save I still > get a javascript error which seems to come from Rails trying to run > the emergency_contact_save.rjs file. > > If I remove the emergency_contact_save.rjs file and again try the > URL /{controller}/emergency_contact_save I get a Rails error saying > there is no rjs file. > > Now, that makes no sense to me at all that Rails should still be > trying to find the rjs file at this point. > > Since that testing, I''ve restarted Rails and that seems to have > changed a few things. Then I ended up building up to this code (added > redirect): > > def emergency_contact_save > > if request.xhr? > .... logger step comfirms an XHR request .... > > respond_to do |request_format| > request_format.js > end > else > .... logger step comfirms a Non-XHR request .... > > redirect_to :action => ''...the basic view of the page...'' > end > > end > > That combination of xhr? and the redirect seems to be the cure. Now, > maybe I need to do some refactoring to allow a legit POST, but for > now this seems to take care of the problem of how to handle Ajax vs > non-Ajax calls. > > Thanks for bouncing some ideas, Nicholas. > > -- gw--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Nicholas Henry
2008-May-13 04:12 UTC
Re: Stumped by Ajax + Session + Saving Model + Private Method
Greg: In addition, I think the catch all route at the end of your routes file will ignore the format and pickup the default template in this order: emergency_contact_save.html.erb emergency_contact_save.rjs.js The respond to stuff would only work strictly if you were using routes defined by resources and you had no catch all route at the end. I might be totally wrong here, but worth a try if you are interested. HTH, Nicholas On May 13, 12:07 am, Nicholas Henry <nicholas.he...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> You could also do something like this at the top of your controller: > > verify :only => ''emergency_contact_save'', :xhr => true. > > That would be nicer than having the conditional statement in the > method > > Nicholas > > On May 12, 11:51 pm, Greg Willits <li...-0Bv1hcaDFPRk211Z5VL+QA@public.gmane.org> wrote: > > > On May 12, 2008, at 8:24 PM, Nicholas Henry wrote: > > > > I think it''s your implementation of the form/params hash that could > > > improve and solve your issue here: > > > Nah, that doesn''t matter. How the model is poulated isn''t relevant. > > I''ve removed the model altogther to better understand what Ajax and > > Rails are doing here, and somehow, Rails is still trying to call the > > RJS template even when the request is not XHR. > > > So, I now have this: > > > def emergency_contact_save > > > if request.xhr? > > .... logger step comfirms an XHR request .... > > > respond_to do |request_format| > > request_format.js > > end > > else > > .... logger step comfirms a Non-XHR request .... > > end > > > end > > > And, I have a file emergency_contact_save.rjs > > > All works fine when using the web UI. > > > When I use a direct URL /{controller}/emergency_contact_save I still > > get a javascript error which seems to come from Rails trying to run > > the emergency_contact_save.rjs file. > > > If I remove the emergency_contact_save.rjs file and again try the > > URL /{controller}/emergency_contact_save I get a Rails error saying > > there is no rjs file. > > > Now, that makes no sense to me at all that Rails should still be > > trying to find the rjs file at this point. > > > Since that testing, I''ve restarted Rails and that seems to have > > changed a few things. Then I ended up building up to this code (added > > redirect): > > > def emergency_contact_save > > > if request.xhr? > > .... logger step comfirms an XHR request .... > > > respond_to do |request_format| > > request_format.js > > end > > else > > .... logger step comfirms a Non-XHR request .... > > > redirect_to :action => ''...the basic view of the page...'' > > end > > > end > > > That combination of xhr? and the redirect seems to be the cure. Now, > > maybe I need to do some refactoring to allow a legit POST, but for > > now this seems to take care of the problem of how to handle Ajax vs > > non-Ajax calls. > > > Thanks for bouncing some ideas, Nicholas. > > > -- gw--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Greg Willits
2008-May-13 04:42 UTC
Re: Stumped by Ajax + Session + Saving Model + Private Method
OK, I''ll check that stuff out -- thanks. -- gw On May 12, 2008, at 9:12 PM, Nicholas Henry wrote:> > Greg: > > In addition, I think the catch all route at the end of your routes > file will ignore the format and pickup the default template in this > order: > > emergency_contact_save.html.erb > emergency_contact_save.rjs.js > > The respond to stuff would only work strictly if you were using routes > defined by resources and you had no catch all route at the end. I > might be totally wrong here, but worth a try if you are interested. > > HTH, > Nicholas > > On May 13, 12:07 am, Nicholas Henry <nicholas.he...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: >> You could also do something like this at the top of your controller: >> >> verify :only => ''emergency_contact_save'', :xhr => true. >> >> That would be nicer than having the conditional statement in the >> method >> >> Nicholas >> >> On May 12, 11:51 pm, Greg Willits <li...-0Bv1hcaDFPRk211Z5VL+QA@public.gmane.org> wrote: >> >>> On May 12, 2008, at 8:24 PM, Nicholas Henry wrote: >> >>>> I think it''s your implementation of the form/params hash that could >>>> improve and solve your issue here: >> >>> Nah, that doesn''t matter. How the model is poulated isn''t relevant. >>> I''ve removed the model altogther to better understand what Ajax and >>> Rails are doing here, and somehow, Rails is still trying to call the >>> RJS template even when the request is not XHR. >> >>> So, I now have this: >> >>> def emergency_contact_save >> >>> if request.xhr? >>> .... logger step comfirms an XHR request .... >> >>> respond_to do |request_format| >>> request_format.js >>> end >>> else >>> .... logger step comfirms a Non-XHR request .... >>> end >> >>> end >> >>> And, I have a file emergency_contact_save.rjs >> >>> All works fine when using the web UI. >> >>> When I use a direct URL /{controller}/emergency_contact_save I still >>> get a javascript error which seems to come from Rails trying to run >>> the emergency_contact_save.rjs file. >> >>> If I remove the emergency_contact_save.rjs file and again try the >>> URL /{controller}/emergency_contact_save I get a Rails error saying >>> there is no rjs file. >> >>> Now, that makes no sense to me at all that Rails should still be >>> trying to find the rjs file at this point. >> >>> Since that testing, I''ve restarted Rails and that seems to have >>> changed a few things. Then I ended up building up to this code >>> (added >>> redirect): >> >>> def emergency_contact_save >> >>> if request.xhr? >>> .... logger step comfirms an XHR request .... >> >>> respond_to do |request_format| >>> request_format.js >>> end >>> else >>> .... logger step comfirms a Non-XHR request .... >> >>> redirect_to :action => ''...the basic view of the page...'' >>> end >> >>> end >> >>> That combination of xhr? and the redirect seems to be the cure. Now, >>> maybe I need to do some refactoring to allow a legit POST, but for >>> now this seems to take care of the problem of how to handle Ajax vs >>> non-Ajax calls. >> >>> Thanks for bouncing some ideas, Nicholas. >> >>> -- gw > >-- def gw acts_as_n00b writes_at ''www.railsdev.ws'' end --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Greg Willits
2008-May-13 05:52 UTC
Re: Stumped by Ajax + Session + Saving Model + Private Method
On May 12, 2008, at 9:07 PM, Nicholas Henry wrote:> You could also do something like this at the top of your controller: > > verify :only => ''emergency_contact_save'', :xhr => true. > > That would be nicer than having the conditional statement in the > methodAh, ok, verify does the exact same thing as the conditional. Interesting. Now, whether it''s "nicer" is questionable IMO. In a case where the same conditions and actions apply to multiple actions, I can see the attraction of eliminating the redundancy, but in cases where it''d be the rare method that uses the verify, IMO having the conditional right in the method code is more explicit, and not prone to missing those details. I''m not a fan of splitting up code like this (again, unless it is something where the redundancy would become tedious, then splitting the code with verify becomes the lesser "evil"). Anyway, I can see that using Ajax requires more planning than just banging out the css and rjs files, and there''s a few options to deal with it. Thanks for your help. -- gw --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Just to clarify, that should be emergency_contact_save.js.rjs <action>.<format>.<renderer> action = ''emergency_contact_save'' format = ''js'' (as in, respond_to do |format| ... format.js... ) renderer = rjs engine (vs erb/haml/builder/etc)> emergency_contact_save.html.erb > emergency_contact_save.rjs.js--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---