Ensuring AR#set_table_name is valid with multiple users

Hi,

due to the legacy nature of my database I have to do a
set_table_name() to make sure that the correct MySQL table is picked
up by the AR model.

For example:

model.set_table_name(params[:use_this_table])

One thing that occurred to me is that if I have multiple users
accessing my app and they’re looking at different tables then I run
the risk that one user’s set_table_name might over-write another’s
leading to incorrect data being sent to the user.

To mitigate the problem I do the set_table_name as close as possible
to the find() or where I write to the database.

Is this a valid concern? Are there more techniques to prevent this
happening or even detect that it happens?

Thanks,

Allan

I’d see this as a HUGE design mistake. That is so thread un-safe.
Imagine rails being thread-safe in next 6 months, and you’ll still be
stuck with a big fat lock around your request.

I’m sure there are other ways to achieve whatever it is you’re trying
to, but this is not a right way. Go with the solution which doesn’t
change global behavior of your models during request serving.

Probably you might end up having 100 models. Which is just fine.

params[:use_this_model].classify.find(:all) = GOOOOOD
model.set_table_name(params[:use_this_table]) && model.find(:all) =
BAD/FUGLY

On 10/25/07, Allan [email protected] wrote:

Thanks,

Allan


Cheers!

Allan wrote:

Hi,

due to the legacy nature of my database I have to do a
set_table_name() to make sure that the correct MySQL table is picked
up by the AR model.

For example:

model.set_table_name(params[:use_this_table])

[…]

To mitigate the problem I do the set_table_name as close as possible
to the find() or where I write to the database.

Another option might be to construct AR classes as needed:

ar_class = SpecialARConstructor.create_class(params[:use_this_table])
ar_class.find(…)
new_row = ar_class.new(…)
new_row.save
etc.

The class definition of the classes created would invoke the desired
set_table_name.

You would need to use the dynamic features of Ruby when implementing the
create_class method in the SpecialARConstructor (module?)

Good luck!

Stephan