Where to put additional code for model.

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

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

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).

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

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)

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.

> 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?

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