I want to use a text field to capture a time interval, e.g. "2 weeks" and have the contoller turn that into a Date before writing to the model (e.g. Time.now + 2.weeks). The text_field form helper is closely wired to the (AR) model, so I can''t use it as there''s that indirect step. I''m pretty clueless about forms. What''s the best Rails way to just get some information to the controller in a text field without writing directly to the model? Thanks, Gavin
You won''t be writing directly to the model if you use the text_field as you are used to. For example, using this in your view: <%= text_field "text", "time" %> In your controller, you will be able to access this as: @params["text"]["time"] You are probably feeling wary of using text_field this way because there is some "magic" going on that may have bad side effects. However, all of the form helper methods will only use the instance variables (e.g. @text) that are indirectly connected to the model if that object itself exists. (In the example above, the text field will only have a default value in it if the @text.time method exists.) Note that "indirectly" means that you would still have to set the values in the model via the controller, so you would never have to worry about your view modifying the model directly. Duane Johnson (canadaduane) On Apr 5, 2005 6:39 PM, Gavin Sinclair <gsinclair-81uBx+iSpXA0n/F98K4Iww@public.gmane.org> wrote:> I want to use a text field to capture a time interval, e.g. "2 weeks" > and have the contoller turn that into a Date before writing to the > model (e.g. Time.now + 2.weeks). > > The text_field form helper is closely wired to the (AR) model, so I > can''t use it as there''s that indirect step. > > I''m pretty clueless about forms. What''s the best Rails way to just > get some information to the controller in a text field without writing > directly to the model? > > Thanks, > Gavin > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
On Wednesday, April 6, 2005, 10:58:06 AM, Duane wrote:> You won''t be writing directly to the model if you use the text_field > as you are used to.> For example, using this in your view:> <%= text_field "text", "time" %>> In your controller, you will be able to access this as:> @params["text"]["time"]> You are probably feeling wary of using text_field this way because > there is some "magic" going on that may have bad side effects. > [...]Actually, the magic I was worrying about was the "automatic" writing to the model, but then I realised it takes place in @widget = Widget.new(@params[:widgets]) So if I need to be more explicit, I can do values = @params[:widgets] @widget = Widget.new do |w| w.name = values[:name] w.date = parse_date_string(values[:date]) ... end Sweet. Thanks! Gavin
Hi, This is just what I''m trying to accomplish. Sometimes I need to get some Miscellaneous info from the user that''s not part of the model. I''ve been using the technique you describe to access the params for example: @params["text"]["anytext"] But I''m confused how I would set the values, I guess I don''t know how to set up the instance method as you described. Could you provide an example of what I would have in the controller to make this happen? Can I just have a line as follows: @text.anytext = "Fred" Or do I have to do something more complicated? I''m sure this is ruby 101... but I''m a little lost. Please provide some detail, because I haven''t grokked this. Thanks, Joe -----Original Message----- From: rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org [mailto:rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On Behalf Of Duane Johnson Sent: Tuesday, April 05, 2005 5:58 PM To: rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org Subject: Re: [Rails] Form question: virtual fields You won''t be writing directly to the model if you use the text_field as you are used to. For example, using this in your view: <%= text_field "text", "time" %> In your controller, you will be able to access this as: @params["text"]["time"] You are probably feeling wary of using text_field this way because there is some "magic" going on that may have bad side effects. However, all of the form helper methods will only use the instance variables (e.g. @text) that are indirectly connected to the model if that object itself exists. (In the example above, the text field will only have a default value in it if the @text.time method exists.) Note that "indirectly" means that you would still have to set the values in the model via the controller, so you would never have to worry about your view modifying the model directly. Duane Johnson (canadaduane) On Apr 5, 2005 6:39 PM, Gavin Sinclair <gsinclair-81uBx+iSpXA0n/F98K4Iww@public.gmane.org> wrote:> I want to use a text field to capture a time interval, e.g. "2 weeks" > and have the contoller turn that into a Date before writing to the > model (e.g. Time.now + 2.weeks). > > The text_field form helper is closely wired to the (AR) model, so I > can''t use it as there''s that indirect step. > > I''m pretty clueless about forms. What''s the best Rails way to just > get some information to the controller in a text field without writing > directly to the model? > > Thanks, > Gavin > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >_______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Gavin and Joe, On 6.4.2005, at 04:12, Gavin Sinclair wrote:> > Actually, the magic I was worrying about was the "automatic" writing > to the model, but then I realised it takes place in > > @widget = Widget.new(@params[:widgets]) > > So if I need to be more explicit, I can do > > values = @params[:widgets] > @widget = Widget.new do |w| > w.name = values[:name] > w.date = parse_date_string(values[:date]) > ... > endRemember that @params hash is editable. So you can also do something like this: @params["widget"]["time"] = do_your_magic(@params["widget"]["time"]) @widget = Widget.new(@params["widget"]) Joe,> > I''ve been using the technique you describe to access the params for > example: > > @params["text"]["anytext"] > > But I''m confused how I would set the values, I guess I don''t know how > to set > up the instance method as you described. Could you provide an example > of > what I would have in the controller to make this happen? > Can I just have a line as follows: > > @text.anytext = "Fred" > > Or do I have to do something more complicated? I''m sure this is ruby > 101... > but I''m a little lost. Please provide some detail, because I haven''t > grokked this.@params hash is just a hash of query variable values that you have to tie to your model somehow. So @text.anytext = "Fred" will set the attribute "anytext" of object @text but it hasn''t got anything to do with the query parameters. The usual way to set all the attributes of a new object based on query vars is this: @text = Text.new(@params["text"]) @text.save Like said above, the @params hash can be massaged before this if needed, but the values can also be transferred to a desired form in the model with before_save and before_validation callbacks [1]. When changing an existing object, the normal way to do it is this: @text = Text.find(1432) @text.attributes = @params["text"] @text.save Note that I''ve left out any validity checks here for simplicity. E.g. hieraki code [2] is full of great examples of how a solid but simple model changing code should look like. //jarkko [1] http://rails.rubyonrails.com/classes/ActiveRecord/ Callbacks.html#M000544 [2] http://dev.hieraki.org/trac.cgi/browser/trunk/ -- Jarkko Laine http://jlaine.net http://odesign.fi _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Jarkko Thanks for your help, but I''m still having problems. Here is my issue more in depth. I have a change email page (part of the the login system) I want to confirm the original email address prior to updating the data/model. Since the original email is not part of the model, I need to treat this as a virtual field. I''m having an issue preloading this field with a default since it''s not part of the model, I tried your approach with setting the @params first and getting errors. Here is a snip of my controller code: def cemail @myerrors = Hash.new case @request.method when :get @params = Hash.new @params["virtual"]["oldemail"] ="Enter your Email Here" #Not working when :post @login = Login.new(@params["login"]) if @params[''virtual''][''oldemail''] != @session[''login''][''email''] then @myerrors = {"Old Email" => "Current Email is incorrect"} End ..... And my View: ... <form action="/holder/cemail" method="POST"> <%= hidden_field "login", "id", "size" => 45 %> <%= hidden_field "login", "password" %> <%= hidden_field "login", "password_confirmation" %> <table width="200" border="1"> <tr> <td>Old Email Address: </td> <td> </td> <td><%= text_field "virtual", "oldemail", "size" => 45 %></td> </tr> <tr> <td>New Email Address: </td> <td> </td> <td><%= text_field "login", "login", "size" => 45 %></td> </tr> <tr> <td>Confirm New Email Address: </td> <td> </td> <td><%= text_field "login", "login_confirmation", "size" => 45 %></td> </tr> </table> <br> <input type="submit" value="Change Email"> </form> On the post all is good, and I''m able to access the virtual field without a problem, I''m just having a problem setting the field to begin with. Also let''s say an error occurs elsewhere in the form when the user resubmits the form, I want it have the prior value before the submit. I''m thinking the Text_field helper is looking for an instance variable of @virtual with something of ."oldemail" rather then setting up the @params[virutal][oldemail] and this is where I''m having an issue. The error I''m getting is: undefined method `[]='' for nil:NilClass I guess maybe the bigger point is, I don''t know how to have an object without having it being created automatically by reflection of the db. I swear I''m not a complete idiot. Thanks, Joe -----Original Message----- From: rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org [mailto:rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On Behalf Of Jarkko Laine Sent: Tuesday, April 05, 2005 11:40 PM To: rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org Subject: Re: [Rails] Form question: virtual fields Gavin and Joe, On 6.4.2005, at 04:12, Gavin Sinclair wrote:> > Actually, the magic I was worrying about was the "automatic" writing > to the model, but then I realised it takes place in > > @widget = Widget.new(@params[:widgets]) > > So if I need to be more explicit, I can do > > values = @params[:widgets] > @widget = Widget.new do |w| > w.name = values[:name] > w.date = parse_date_string(values[:date]) > ... > endRemember that @params hash is editable. So you can also do something like this: @params["widget"]["time"] = do_your_magic(@params["widget"]["time"]) @widget = Widget.new(@params["widget"]) Joe,> > I''ve been using the technique you describe to access the params for > example: > > @params["text"]["anytext"] > > But I''m confused how I would set the values, I guess I don''t know how > to set > up the instance method as you described. Could you provide an example > of > what I would have in the controller to make this happen? > Can I just have a line as follows: > > @text.anytext = "Fred" > > Or do I have to do something more complicated? I''m sure this is ruby > 101... > but I''m a little lost. Please provide some detail, because I haven''t > grokked this.@params hash is just a hash of query variable values that you have to tie to your model somehow. So @text.anytext = "Fred" will set the attribute "anytext" of object @text but it hasn''t got anything to do with the query parameters. The usual way to set all the attributes of a new object based on query vars is this: @text = Text.new(@params["text"]) @text.save Like said above, the @params hash can be massaged before this if needed, but the values can also be transferred to a desired form in the model with before_save and before_validation callbacks [1]. When changing an existing object, the normal way to do it is this: @text = Text.find(1432) @text.attributes = @params["text"] @text.save Note that I''ve left out any validity checks here for simplicity. E.g. hieraki code [2] is full of great examples of how a solid but simple model changing code should look like. //jarkko [1] http://rails.rubyonrails.com/classes/ActiveRecord/ Callbacks.html#M000544 [2] http://dev.hieraki.org/trac.cgi/browser/trunk/ -- Jarkko Laine http://jlaine.net http://odesign.fi
Joe, @params hash is the information you get from a submitted form. You cannot use it before a form has been submitted (i.e. in :get part of the action). What I''d do in your case is this: On 6.4.2005, at 20:53, Joseph Lyons wrote:> def cemail > @myerrors = Hash.new > case @request.method > when :get > @params = Hash.new > @params["virtual"]["oldemail"] ="Enter your Email Here" #Not > workingReplace this with: @oldemail = "Enter your Email Here"> > when :post > @login = Login.new(@params["login"]) > > if @params[''virtual''][''oldemail''] != @session[''login''][''email''] then > @myerrors = {"Old Email" => "Current Email is incorrect"} > End > ..... > > And my View: > ... > <form action="/holder/cemail" method="POST"> > <%= hidden_field "login", "id", "size" => 45 %> > <%= hidden_field "login", "password" %> > <%= hidden_field "login", "password_confirmation" %> > <table width="200" border="1"> > <tr> > <td>Old Email Address: </td> > <td> </td> > <td><%= text_field "virtual", "oldemail", "size" => 45 %></td>This assumes that you have an object @virtual which has an attribute oldemail defined in your controller action (which you do not). The value of this field could be reached _after you post the form_ in @params["virtual"]["oldemail"]. Anyway, text_field helper is pretty closely tied to AR objects, which you don''t have at hand in this case. So replace it with: <input id="virtual_oldemail" name="virtual[oldemail]" size="45" type="text" value="<%= @oldemail %>" /> After that the post part of your action should work fine as it is now. Except you need to add @oldemail = @params["virtual"]["oldemail"] so that you have the value at hand if you need to render the form again if some other field doesn''t pass the validation. //jarkko -- Jarkko Laine http://jlaine.net http://odesign.fi _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
On Thursday, April 7, 2005, 4:31:43 AM, Jarkko wrote:> So replace it with: > <input id="virtual_oldemail" name="virtual[oldemail]" size="45" > type="text" value="<%= @oldemail %>" />Couldn''t that be <%= text_field "virtual", "oldemail", :size => 45, :value => @oldemail %> ?> After that the post part of your action should work fine as it is now. > Except you need to add @oldemail = @params["virtual"]["oldemail"]I don''t understand this bit. That''s _after_ the form is submitted, right? (If so, OK.) Gavin
On 06/04/2005, at 10:39 AM, Gavin Sinclair wrote:> I want to use a text field to capture a time interval, e.g. "2 weeks" > and have the contoller turn that into a Date before writing to the > model (e.g. Time.now + 2.weeks). > > The text_field form helper is closely wired to the (AR) model, so I > can''t use it as there''s that indirect step.You want text_field_tag, not text_field. You can then access it using @params, do your processing and set your model attribute accordingly. Check out the form tag helper docs (as opposed to the form helper docs): http://rails.rubyonrails.com/classes/ActionView/Helpers/ FormTagHelper.html> I''m pretty clueless about forms. What''s the best Rails way to just > get some information to the controller in a text field without writing > directly to the model?as above. Many people are stumped by the Form Helper vs Form Tag Helper. Might I suggest Form Helper be renamed to AR Form Helper or something similar? - tim lucas
Gavin, On 6.4.2005, at 23:51, Gavin Sinclair wrote:> On Thursday, April 7, 2005, 4:31:43 AM, Jarkko wrote: > >> So replace it with: >> <input id="virtual_oldemail" name="virtual[oldemail]" size="45" >> type="text" value="<%= @oldemail %>" /> > > Couldn''t that be > > <%= text_field "virtual", "oldemail", :size => 45, :value => > @oldemail %>No, unless you have object @virtual with attribute oldemail at hand. text_field implies that it is working on an AR object which is not the case here. Like Tim said, though, it can be <%= text_field_tag "oldemail", @oldemail, :size => 45 %> Then the value would be @params["oldemail"] in the action where the form is submitted (as opposed to @params["virtual"]["oldemail"]).> >> After that the post part of your action should work fine as it is now. >> Except you need to add @oldemail = @params["virtual"]["oldemail"] > > I don''t understand this bit. That''s _after_ the form is submitted, > right? (If so, OK.)Yes. With "post part of an action" I mean the part inside "when :post". That always means that the form is submitted. If you take a look at Joe''s controller, you can see that the action is separated in two parts according to @request.method. :get is when the form page is normally requested. :post gets hit when the form has been submitted to itself (using <form method="post"> of course). You need to add that line to the action because if the form submission (validation) fails, the action probably renders the same form again. In that case you want to prepopulate the field with the value user had already put there. The form view assumes that the value is in @oldemail (not @params["oldemail"]) so you have to assign the correct value to that variable. Hth, //jarkko -- Jarkko Laine http://jlaine.net http://odesign.fi _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Hello, and don''t you want just add attr_accessor :interval to your model. But maybe I got it wrong. -- Pepe On 6.4.2005, at 2:39, Gavin Sinclair wrote:> I want to use a text field to capture a time interval, e.g. "2 weeks" > and have the contoller turn that into a Date before writing to the > model (e.g. Time.now + 2.weeks). > > The text_field form helper is closely wired to the (AR) model, so I > can''t use it as there''s that indirect step. > > I''m pretty clueless about forms. What''s the best Rails way to just > get some information to the controller in a text field without writing > directly to the model? > > Thanks, > Gavin > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >