Forum: Ruby on Rails Where to put additional code for model.

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Cb880dd8c8c209924ebb57edbb4fcd06?d=identicon&s=25 Jim Burgess (jim_in_germany)
on 2009-05-12 08:24
Hi,
I have written a method to map three 'virtual' fields in my form to one
'proper' field in my model.
It looks like this:

class Class
  def map_three_fields(var1, var2, var3)
    string_val = "...do stuff..."
   self.class_eval string_val
  end
end

At the moment it is sitting at the top of my model, but the method is
quite long and this looks a bit ugly / cluttered.

Is there anywhere else I can put this code?
And if so, will it work out of the box or do I need to add a "require"
somewhere or alter any configuration files.

Thanks for your help
54404bcac0f45bf1c8e8b827cd9bb709?d=identicon&s=25 7stud -- (7stud)
on 2009-05-12 10:20
Jim Burgess wrote:
> Hi,
> I have written a method to map three 'virtual' fields in my form to one
> 'proper' field in my model.
> It looks like this:
>
> class Class
>   def map_three_fields(var1, var2, var3)
>     string_val = "...do stuff..."
>    self.class_eval string_val
>   end
> end
>
> At the moment it is sitting at the top of my model, but the method is
> quite long and this looks a bit ugly / cluttered.
>
> Is there anywhere else I can put this code?
>

In my opinion (backed by zero experience), models are serfs, and
controllers are the aristocrats that command the serfs to do various
chores.  So if you think a controller is going to get its hands dirty
doing the work of a serf, well...you better think again.

Of course you could create another model--one not hooked up to a
database--that has a class method that you could call like this:

Utilities.map_three_fields()

And no, you wouldn't need a require.
5f94b9b346c2aa648a80bc259978e5bc?d=identicon&s=25 Colin Law (Guest)
on 2009-05-12 10:37
(Received via mailing list)
2009/5/12 Jim Burgess <rails-mailing-list@andreas-s.net>

>  end
> end
>
> At the moment it is sitting at the top of my model, but the method is
> quite long and this looks a bit ugly / cluttered.


You could put it down the end of the model, it should be in the private
section anyway, presumably.
If it is that ugly/cluttered you could refactor it.
Colin
Bce1d1b7c3ec7b577dcb42e254899e6b?d=identicon&s=25 Michael Schuerig (Guest)
on 2009-05-12 11:35
(Received via mailing list)
On Tuesday 12 May 2009, Jim Burgess wrote:
> end
I hope you know what you're doing. What if one of the strings is

%x{echo gotcha}

or worse?

> At the moment it is sitting at the top of my model, but the method is
> quite long and this looks a bit ugly / cluttered.

Then move it down to the bottom, or if you want to hide it even more,
put it in a module:

class MyModel < ActiveRecord::Base
  include ComplicatedStuff
  ...
end

> And if so, will it work out of the box or do I need to add a
> "require" somewhere or alter any configuration files.

As long as it is in one of the "usual" directories, i.e. app/models,
lib, the module will be found automatically.

Michael

--
Michael Schuerig
mailto:michael@schuerig.de
http://www.schuerig.de/michael/
Cb880dd8c8c209924ebb57edbb4fcd06?d=identicon&s=25 Jim Burgess (jim_in_germany)
on 2009-05-12 11:56
Hi,

Thanks very much for the replies.
I will follow Michael's advice and stick it in a module.

> I hope you know what you're doing.

Probably nowhere near as much as I should

> What if one of the strings is
> %x{echo gotcha}
> or worse?

It's a date input which is mapped.
In the model the field is :dob and is a string.
In the form this is split into :dob_day, :dob_month, :dob_year

Using the method I wrote (currently) in my model I can them write:
map_three_fields :dob_day, :dob_month, :dob_year

and they are returned as a string containing a date in the form of
"dd-mm-yyyy" (including hyphens).

In the form the maximum length of dob_day and dob_year are 2 characters.
The maximum length of dob_year is 4 characters.

Therefore (I hope) it is not possible to enter "%x{echo gotcha}".

Now the question to make you slap your hand on your head and look at the
ceiling:
What would this do, anyway?

Do you have any comments, ideas, criticism about doing things this way?

I found relatively little on the inputing of dates in forms using Rails
online (date select is genuinely rubbish) and the form should also run
without javascript. Therefore I put this method together myself and
would be very grateful if anyone could point out if there are any
massive security exploits that I have overlooked.

If it would help I can post the full code of what I have done.

Thanks very much in advance.
Bce1d1b7c3ec7b577dcb42e254899e6b?d=identicon&s=25 Michael Schuerig (Guest)
on 2009-05-12 12:24
(Received via mailing list)
On Tuesday 12 May 2009, Jim Burgess wrote:
> > %x{echo gotcha}
> "dd-mm-yyyy" (including hyphens).
Why? IMHO, the best you can do is have a look at how date_select works,
you'll notice that it already does what you're trying to do. For the
long story see the code in date_helper.rb and date_helper_test.rb
somewhere in ActionView and
Activerecord::Base#assign_multiparameter_attributes. For the short
story, name your fields

dob(1i), dob(2i), and dob(3i) and have ActiveRecord put together these
parts.

> In the form the maximum length of dob_day and dob_year are 2
> characters. The maximum length of dob_year is 4 characters.
>
> Therefore (I hope) it is not possible to enter "%x{echo gotcha}".

Careful! It may not be possible to enter anything exceeding the max
length in the average browser, but that doesn't stop anyone to submit
requests to your app with other tools.

>
> Now the question to make you slap your hand on your head and look at
> the ceiling:
> What would this do, anyway?

%x{echo gotcha} is another way of writing `echo gotcha`. Each of these
executes the given command(s) with the right of the current user. It's
like that you wouldn't enter cd $HOME; rm -rf by yourself, so you'd
better not give someone else an opportunity to enter %x{cd $HOME, rm -
rf} for you.


> Do you have any comments, ideas, criticism about doing things this
> way?
>
> I found relatively little on the inputing of dates in forms using
> Rails online (date select is genuinely rubbish) and the form should
> also run without javascript. Therefore I put this method together
> myself and would be very grateful if anyone could point out if there
> are any massive security exploits that I have overlooked.

Passing arbitrary, user-provided strings to eval or class_eval *is* a
huge security hole.

Michael

--
Michael Schuerig
mailto:michael@schuerig.de
http://www.schuerig.de/michael/
Cb880dd8c8c209924ebb57edbb4fcd06?d=identicon&s=25 Jim Burgess (jim_in_germany)
on 2009-05-12 13:07
Hi Michael,
Thanks for the reply.

>> "dd-mm-yyyy" (including hyphens).
> Why? IMHO, the best you can do is have a look at how date_select works,
> you'll notice that it already does what you're trying to do.

But isn't date_select really feeble?
For example it is very easy to make the whole application crash by
giving date_select false input (eg. enetering 31st February with no
year. http://www.ruby-forum.com/topic/183310)

> Careful! It may not be possible to enter anything exceeding the max
> length in the average browser, but that doesn't stop anyone to submit
> requests to your app with other tools.

Good point.

> %x{echo gotcha} is another way of writing `echo gotcha`. Each of these
> executes the given command(s) with the right of the current user. It's
> like that you wouldn't enter cd $HOME; rm -rf by yourself, so you'd
> better not give someone else an opportunity to enter %x{cd $HOME, rm -
> rf} for you.

Even better point.

> Passing arbitrary, user-provided strings to eval or class_eval *is* a
> huge security hole.

You're right.
I did have everything working without using eval.
The method with eval was just intended to make everything that bit
neater.
Would it then be sufficient to check the user generated input for
numericality (ie. enduse that the user has only entered numbers as they
are supposed to) and only carry out eval in this case, or would that
make no difference?
Bce1d1b7c3ec7b577dcb42e254899e6b?d=identicon&s=25 Michael Schuerig (Guest)
on 2009-05-12 15:04
(Received via mailing list)
On Tuesday 12 May 2009, Jim Burgess wrote:
> giving date_select false input (eg. enetering 31st February with no
> year. http://www.ruby-forum.com/topic/183310)

The app does not crash, it just reacts with an exception to malformed
input data. I think Fred Cheung's suggestion in that thread is
completely right: Catch that exception and handle it. From the
ActiveRecord::MultiparameterAssignmentErrors exception you can even find
out which attributes were involved an generate a nice error message.

> that make no difference?
You can, of course, do your own sanitizing of input data. But in this
particular case I don't see the point. You still need to avoid anomalies
like February, 31st. I don't see any advantage in doing this stuff
yourself instead of giving ActiveRecord a chance and mop up in case it
indicates a problem. Don't get to enamored with your current approach.

Michael

--
Michael Schuerig
mailto:michael@schuerig.de
http://www.schuerig.de/michael/
Cb880dd8c8c209924ebb57edbb4fcd06?d=identicon&s=25 Jim Burgess (jim_in_germany)
on 2009-05-12 15:21
Ok, cheers for that.
I guess I will have to rethink my approach.
In defense of my current method, to make sure the date field doesn't
accept incorrect input I use ruby's 'Date.strptime' to parse the string
as a date. If it works then everything is ok, if it throws an error then
I catch this and output the error message that the date is invalid.

>> that make no difference?
> You can, of course, do your own sanitizing of input data. But in this
> particular case I don't see the point. You still need to avoid anomalies
> like February, 31st. I don't see any advantage in doing this stuff
> yourself instead of giving ActiveRecord a chance and mop up in case it
> indicates a problem. Don't get to enamored with your current approach.
D188e591eac11021329b8821a5f954c7?d=identicon&s=25 Ar Chron (railsdog)
on 2009-05-12 16:09
Jim Burgess wrote:
>
> At the moment it is sitting at the top of my model, but the method is
> quite long and this looks a bit ugly / cluttered.
>

Sometimes code is ugly no matter what... ;)

I remember having to account for the difference between little-endian
veruss big-endian architectures on a project, and writing a whole
comment paragraph about just why I was twiddling two bytes of data in
the buffer stream before extracting it into the long int I wanted...

> Is there anywhere else I can put this code?

If it belongs to the model, it should be in the model, unless it really
is a larger 'sub-system' that merits its own module.

Of course, it *could* always be just the first entry into your
'application_extensions' module as well, but when I find modules with
just one or two methods that are only used by one class, there's a 'Why
oh why?' moment.

Just my $0.02.
54926dd0eeb29e2d1f75d74e401ff576?d=identicon&s=25 p_W (Guest)
on 2009-05-12 21:10
(Received via mailing list)
So this won't fix the problem of user input outside the browser, but
what about implementing the date fields as <select>'s instead of text
fields?  You will still have to sanitize the data but at least you
have defined the format in which the user inputs it through the
browser.

On May 12, 10:09 am, Ar Chron <rails-mailing-l...@andreas-s.net>
065cc6140c6a1320fa2aa87eaa98a2ed?d=identicon&s=25 Aaron Brown (Guest)
on 2009-05-12 21:41
(Received via mailing list)
p_W wrote:
> So this won't fix the problem of user input outside the browser, but
> what about implementing the date fields as <select>'s instead of text
> fields?  You will still have to sanitize the data but at least you
> have defined the format in which the user inputs it through the
> browser.

I recommend this setup for date entry since it does help a little with
the input sanitizing:  When you use a Select tag, the user input options
are known values and it allows you to be much more aggressive and
unforgiving with your input validation.  Text box input requires some
fuzzy acceptance of values, but a Select/Options list does not - you can
validate against a fixed set of values and anything else must have come
from a Bad Guy.

 - Aaron
Cb880dd8c8c209924ebb57edbb4fcd06?d=identicon&s=25 Jim Burgess (jim_in_germany)
on 2009-05-12 21:47
> I recommend this setup for date entry since it does help a little with
> the input sanitizing:  When you use a Select tag, the user input options
> are known values and it allows you to be much more aggressive and
> unforgiving with your input validation.  Text box input requires some
> fuzzy acceptance of values, but a Select/Options list does not - you can
> validate against a fixed set of values and anything else must have come
> from a Bad Guy.

Hi,
Thanksfor the replies.
I've just been chatting with my brother-in-law who is a ruby programmer
(considerably better than am I) and he pointed out that as I am calling
the method which uses "eval" thus:
map_three_fields :dob_day, :dob_month, :dob_year, "make_date", "dob"
the method doesn't accept any user input as arguments (only three
symbols and two strings) and is therefore harmless.

So I guess I can stick with my original method after all.

Cheers
Jim
This topic is locked and can not be replied to.