May a model know about the "outside world"?

Hi all

Most of my models have the attribute creator_id which is a foreign key
to a member. Also many have the attribute owner_id, which is a foreign
key to a member, too.

When being created, both attributes (if available) should get the ID of
the currently logged in member.

To implement this, I could “just” send the currently logged in member’s
ID to the model:

@my_model = MyModel.new(params[:my_model])
@my_model.creator = logged_in_member
@my_model.owner = logged_in_member
@my_model.save

Another way would be to leave it to the model itself to take care of
this, because when creating a new instance of it always a member is
logged in, so the model could somehow get the logged_in_member itself.

But now, would this injure the MVC principle? As far is I know the model
should not know anything about the “outside world”, right?

Or would you suggest a wholy different approach?

Thanks for your opinion
Josh

How would the model know about the logged in user if you don’t specify?
The
model doesn’t have access to controller or session information.

A cleaner way would be:

logged_in_member.my_models.create(params[:my_model])

then in the MyModel#before_save:

if self.owner.nil?
self.owner = self.creator
end

Jason

There’s a way to hack rails to make this happen. It violates every MVC
convention known and is a horrible idea.

The best approach is to do what you suggested… set it in the
controller.

Thank you both for your anwers. :slight_smile:

On 10/19/07, Brian H. [email protected] wrote:

There’s a way to hack rails to make this happen. It violates every MVC
convention known and is a horrible idea.

Yikes!

I don’t think it’s such a horrible idea if implemented properly. I’m
successfully using a slightly modified version of Bruce P.’
ModelSecurity library quite successfully.

The very high-level idea is:

  • The User model (or its equivalent) has a “current” method that
    returns a User object representing the currently logged-in user. All
    model code that needs to know the current user accesses User.current

  • A before_filter in ApplicationController assigns User.current

  • Thread-local storage is used to hold the value, since globals aren’t
    thread-safe.