All functions defined in models are available to controllers and views
as anything you put in the models becomes part of the global namespace
that the controllers/views are executed in.

This leads to potential problems of namespace collision.

Make sure you do not overwrite the function elsewhere, as this could
be causing issues.

Why are you calling db.create_object? This isn't a class of the DAL,
refer to Yarko's explanation, the DAL is not an ORM.

You probably mean.

  if form.accepts(request.vars, session):
       foo = create_object(owner_id=auth.auth_id, # NOT
db.create_object, just call your function like regular
template_name=form.vars.template)



--
Thadeus





On Fri, Jun 4, 2010 at 11:39 AM, Doug Warren <[email protected]> wrote:
> On Fri, Jun 4, 2010 at 9:11 AM, Yarko Tymciurak
> <[email protected]> wrote:
>>
>>
>> On Jun 4, 10:58 am, Doug Warren <[email protected]> wrote:
>>> I don't believe I want to local_import my db.py file as it's already
>>> set up by the environment correct?
>>
>> Correct - you do not want / need to import your db.py.
>>
>> As long as it is in your models folder (by default it is), it's
>> already in your request context before your controller is called.
>
> Yes but as I mentioned in my original E-Mail, I was unable to get a
> function defined in the model file to be visible to the controller
> hence the original question. :)
>
> I thought about it a bit during my drive and think I will try (using
> the below example) something like:
> def create_object...
> ...
>
> co = create_object
>
> controller.py
>  co( template_id ...)
>
>>
>>>
>>> What I'm asking for is a way to keep all of the code that relates to
>>> the model in one place and to invoke it from controllers.  That is if
>>> I define 5 tables for the model I'd expect to write helper functions
>>> to manipulate all 5 tables and not to have the controller know the
>>> intimate details of the model.  That's the concept behind Object
>>> Orientated programming isn't it?  Objects are black boxes to other
>>> objects other than their public facing interface.
>>
>> Right - but DAL is just a Data abstraction layer (i.e. an SQL adapter,
>> if you will), not an ORM (i.e. there's not the level of object-
>> oriented abstraction that you would expect w/ an orm - it's lower
>> level)
>>
>> So in web2py, with DAL you have knowledge of your table layout
>> (without direct knowledge / need for the specific back ends SQL).
>>
>> You'll also find that forms, and validators are coupled to table
>> structure, so if / as you try to abstract away from table definitions,
>> you will run into this.
>>
>> I'm sure others will add more comments...
>>
>>>
>>> On Fri, Jun 4, 2010 at 8:56 AM, Yarko Tymciurak
>>>
>>> <[email protected]> wrote:
>>>
>>> > On Jun 4, 10:43 am, Doug Warren <[email protected]> wrote:
>>> >> Traditionally when I've written MVC style applications, the model
>>> >> would contain not only the data representing the objects but also the
>>> >> data for manipulating the objects.  I'm not sure how that same
>>> >> relation applies to web2py.
>>>
>>> >> If I have a model that defines 4-5 tables, 2 of them are just foreign
>>> >> key lookups, and creating a new object involves inserting data into 3
>>> >> of the tables, it seems that I would want a create_object method in my
>>> >> model file.
>>>
>>> >> So I write something like:
>>>
>>> >> def create_object(owner_id=None, template=None):
>>> >>     # Some sanity checking on the above
>>> >>     new_object = db.objects.insert(template_id=template.id, 
>>> >> person_id=owner_id)
>>>
>>> >>     widgets = db.template_widget(db.template_widget.thingy_template_id
>>> >> == template.id).select()
>>> >>     for widget in widgets: db.thingy_widget.insert(widget_id =
>>> >> widget.id, thingy_id = new_object)
>>>
>>> >>     whatchymacallits =
>>> >> db.template_whatchymacallit(db.template_whatchymacallit.thingy_template_id
>>> >> == template.id).select()
>>> >>     for whatchymacallit in whatchymacallits:
>>> >> db.thingy_whatchymacallit.insert(whatchymacallit_id =
>>> >> whatchymacallit.id, thingy_id = new_object)
>>>
>>> >>     return new_object
>>>
>>> >> and place that into my db.py.  Now the controller has a function like:
>>> >> def create():
>>> >>     form = SQLFORM.factory( Field('template',
>>> >> requires=IS_IN_SET(__get_templates())))
>>> >>     if form.accepts(request.vars, session):
>>> >>         foo = db.create_object(owner_id=auth.auth_id,
>>> >> template_name=form.vars.template)
>>> >>         response.flash = "Created"
>>> >>     elif form.errors:
>>> >>         response.flash = "Error (hacker)"
>>>
>>> >> Well db is referring to the DAL db not the db.py, from db import
>>> >> create_object gives a name not found error, so I'm at a loss as to how
>>> >> to define functions that work upon the model and can be invoked from
>>> >> one or more controllers.
>>>
>>> > I'm not sure what exactly you are saying here - but to import, use
>>> > local_import()
>>> > (seehttp://www.web2py.com/book/default/section/4/18?search=local_import)
>>>
>>> > BUT before you do, here is some background:
>>>
>>> > When a request comes into web2py,   here's what happens (roughly):
>>>
>>> > web2py parses the request url, and sets up an environment to call the
>>> > appropriate application / controller / function;
>>> > Part of that setup involves running all the files in your app's  model
>>> > folder (so that db connections, table definitions, etc. are all "there
>>> > for you");
>>>
>>> > This means you can put your files in the models folder, and they will
>>> > be run (defined) before the call to your controller.
>>>
>>> > Then, your controller / function is called.
>>>
>>> > local_import will pull in definitions / modules from your
>>> > application's modules folder, but you can (for development certainly)
>>> > just put your file in your models folder.
>>> > When you really want to reduce what gets run at _each_ request, you
>>> > might want to look at what to move to modules, so that you're only
>>> > pulling in those files when needed.
>>>
>>> > As for db - DAL:   db is the "global" and "default"  name for the db
>>> > connection string (it is so named and setup in the default models/
>>> > db.py file).   You can change the name of this variable as you like
>>> > (or change your imports).
>>>
>>> > Hope this at least helps point you out of the forrest.
>>>
>>> > Regards,
>>> > - Yarko
>>> >> Are there any non-trivial example
>>> >> applications for web2py?  Most of the ones that I have seen assumes
>>> >> that all data you need in the database can be supplied from a form and
>>> >> that's not the case I run into over and over again.
>

Reply via email to