NAME¶
Jifty::Manual::ObjectModel -- An overview of the Jifty object model
OVERVIEW¶
Jifty applications are generally built in a similar way. There's no reason you
need to use the model we've built, but we find it a reasonably OK way
to do things.
This document should serve as a roadmap to the Jifty class library, as well as
an introduction to the way Jifty applications are put together.
We start with the classes in
your application and move on to the bits of
Jifty itself.
If you create a brand new application, let's call it "MyWeblog", and
create one model class called "MyWeblog::Post", you'll end up with
the following files and directories:
MyWeblog/
etc/
config.yml
lib/
MyWeblog/
Model/
Post.pm
Action/
bin/
jifty
web/
templates/
static/
t/
#some test files.
At least that's the scaffolding Jifty creates for you. Behind the scenes, Jifty
is actually doing a lot more. Rather than create a bunch of little
"stub" classes and libraries for you, Jifty generates them on the
fly. It's always possible to
actually create these libraries when you
need to customize the default behavior, but we work really hard to make sure
you don't need to.
Right now, Jifty is automatically creating libraries, static web pages and web
templates.
We're not 100% satisfied with how Jifty automatically creates web templates and
static pages and are working to redesign that.
The library you
see when creating a Jifty app is:
- MyWeblog::Model::Post
- "MyWeblog::Model::Post" describes the schema and
business logic of your post class. It uses two namespaces,
"MyWeblog::Model::Post::Schema" that has actual column
definitions and "MyWeblog::Model::Post" that contains the
(optional) business logic, access control and so on.
That's it. But if you look carefully at "MyWeblog::Model::Post",
you'll see the line:
use base qw/MyWeblog::Record/;
How can that possibly work? There is no "MyWeblog::Record" class in
your application. And Jifty, while it tries to be a comprehensive framework,
draws the line somewhat short of including application-specific base classes
for every application you might possibly contrive.
The answer lies in Jifty::ClassLoader, a utility module Jifty uses to create the
boring stuff for you when you need it.
It'd certainly be possible for Jifty to create every class you might need as a
file on disk when you first create your application (and indeed we may decide
to do so if enough people yell at us), but when the stub classes we'd provide
are just little shims that inherit from or call to the Jifty core, it doesn't
make much sense to create them before you need them. You could build a Jifty
application without these shims by having your model classes inherit directly
from Jifty::Record, but then you'll run into trouble the second you want to
add application-specific code and have to go back and retrofit each and every
one of your classes to use your new base class. It's a little thing, but one
that can save you a bunch of pain and suffering later on.
"MyWeblog::Record" is the first autogenerated class you'll run into
but probably not the last. A full list of everything Jifty provides for your
new application follows:
You get one each of the these:
- MyWeblog::Record
- This class is, as discussed above, a thin wrapper around
Jifty::Record. You might choose to create your own
"MyWeblog::Record" if you want to build in custom access control
by overriding "current_user_can" in Jifty::Record or want to
implement methods that every model class should have access to.
- MyWeblog::Collection
- We haven't talked much about collections yet, but as their
name implies, collections are bundles of Jifty::Record objects that match
some set of criteria. It's relatively uncommon that you'll want to
override this, but if you want the rope, it's here.
- MyWeblog::Notification
- "MyWeblog::Notification" is an app-specific
implementation of the Jifty::Notification email driver. You might want to
override this class if you want to set an application-specific header or
footer for all outgoing email.
- MyWeblog::Dispatcher
- "MyWeblog::Dispatcher" is an application-specific
"dispatcher" class that allows you to write code that runs when
a client makes a request to the server before Jifty runs
actions or renders templates. See Jifty::Dispatcher for more
information about the dispatcher.
- MyWeblog::CurrentUser
- Most every web application that grows past a personal hack
eventually starts to provide personalization, require access control or
otherwise want to know who's currently in the driver's seat. The
"current user" for an application is a first-class object in
Jifty. To get user-based authentication working out of the box, you'll
have to override the default "MyWeblog::CurrentUser". (Out of
the box, it treats everyone as the same user.) We're working to generalize
the authentication system we've used in a few Jifty apps so far to the
point where it feels "right" as a core Jifty component, but
we're not quite there just yet.
Most of what you'll need to override in "MyWeblog::CurrentUser" is
the "_init" function, which needs to load up an
application-specific model class that represents one of your users into
its "user_object" accessor. To make all this work, you'll also
need an application-specific "MyWeblog::Action::Login" and
likely also a passel of user-management code.
(And yes, this is the topic of a future generalization and a future
tutorial. At that point, a bunch of this documentation will be extracted
to Jifty::CurrentUser.)
But wait! There's more! You also get one each of these for your default model
class:
- MyWeblog::Model::PostCollection
- It's no fun having a weblog that only shows you one post at
a time, is it? Jifty provides you with default Jifty::Collection classes
for every Jifty::Record subclass in your model. You get all the standard
"limit", "order_by", "columns", paging
support and so-on out of the box, but sometimes when you're going to be
getting collections matching certain criteria often, it makes sense to
actually create your own subclass and start dropping methods in.
- MyWeblog::Action::CreatePost, MyWeblog::Action::UpdatePost,
MyWeblog::Action::DeletePost
- One of Jifty's strengths is that it makes it easy to build
applications by tying application-specific controller functions to your
model classes and intuiting what parameters they take by having a look
inside the models.
For each class in your model, Jifty creates three actions,
"Create","Update" and "Delete". They're
named, perhaps a bit unadventureously,
"MyWeblog::Action::CreatePost",
"MyWeblog::Action::UpdatePost",
"MyWeblog::Action::DeletePost" and inherit directly from
Jifty::Action::Record::Create, Jifty::Action::Record::Update and
Jifty::Action::Record::Delete, respectively. Sometimes, it makes sense to
override these default actions when you want to change the behaviour of
one or more of the actions. One common use is to add or remove AJAX
validation or autocompletion for an argument or to change an argument's
default value for webforms. This, isn't, however the place to start
inserting business logic or access control. That belongs in your model
class, which these wrappers will hand things off to. By putting logic in
your actions, you make your model classes less useful and run into trouble
when you want to start scripting your model outside a web
environment.
There's no reason you need to stick with these default
"implementations" if they're not meeting your needs. Just create
your own classes and Jifty will use your real classes instead.