On Apr 30, 7:03 am, Pavel Skvazh <
pavel.skv...@gmail.com> wrote:
> Checking if the current user can
> delete a certain letter (if he's the author of it)
> should obviously be done inside the model, but where will I get the
> user_id to check? Passing it to the
> delete function looks just wrong to me.
> Giving the model access to the session looks far from being good MVC
> practice, but I couldn't figure a better way.
That is a bad design pattern for both MVC and OOP standpoints. The
model's core functions should not depend on Pylons or anything 'web'
oriented. You're not liberating the model class, you're creating a
dependency.
Personally, I think your code should be something like :
Controller - SentBox:
letter=
model.letter().load__by__userIdSender_letterId( session['user_id'],
letter_id )
if not letter:
return invalid_letter()
letter.is_deleted_by_sender= True
Model:
class letter():
def load__by__userIdSender_letterId( user_id , letter_id ):
sql= 'select * from letter where ( user_id_sender = %d ) and
( letter_id = %d ) and ( is_deleted_by_sender is not true )"
or
letter= Session.query(self.__class__).filter_by( letter_id =
letter_id ).first()
sql= 'select * from letter where ( letter_id = %d )"
if not letter:
raise ValueError('invalid letter')
if letter.sender_id is not user_id:
raise ValueError('not sender')
if letter. is_deleted_by_sender is true:
raise ValueError('deleted')
return letter
def load__by__userIdRecipient_letterId( user_id , letter_id ):
pass
you could also generate model functions like:
def mark_deleted__by__userIdSender_letterId( user_id , letter_id ):
affected_rows= 'update letter set is_deleted_by_sender = True
where ( user_id_sender = %d ) and ( letter_id = %d )"
but the idea is that, from an access control standpoint, you shouldn't
really do a simple 'load by id' on permissioned records during a write
session. you should always require the ownership data on the record
access and all update/delete object. you can also integrate multiple
db handles - with some being read-only and others being read-write.
mini rant:
i think ORMs and some rapid dev frameworks promote bad practices
with constant 'load by id then check later' actions in the
controller. i keep seeing a lot of controller functionality that
would be better put in the model classes -- where it functions more
like an internal API
think of it like a database view -- the tables/query that make up
the view change a lot, but you have one central interface to access
it. if you treat your models like that (and if you use views, you
already have this ingrained), you can update the 'can i admin'
requirements in a single place, deprecating outdated mechanisms and
avoiding db integrity issues.