Here are (uncategorized) questions (and hopefully answers) from early adopters.
How do I delete all records from a table using a Model?
Question
# empty table my $system_user = CalLabCert::CurrentUser->superuser; my $collection = CalLabCert::Model::DatFileCollection->new(current_user => $system_user); $collection->unlimit(); while (my $item = $collection->next) { $item->delete };
Migrate My Database ?
Question
I have a production database that I have to keep. But my new fancy Jifty function requires a schema update. How should I migrate my production database ?
Answer
Edit etc/config.yaml and change Database->Version to a proper value (say, 0.0.2). Then run
jifty schema --setup
Emulate 'created_on' field like Rails?
Question
In Rails, if you have a field named 'created_on', it's automatically set to the creation time of the record. How can I emulate this behaviour in Jifty ?
Answer
The trick here is to use Scalar::Defer. And declare your column like this:
column created_on =>
type is 'timestamp',
label is 'Created On',
default is defer { DateTime->now },
filters are 'Jifty::DBI::Filter::DateTime';
Use SQLite instead of PostgreSQL?
Question
I edited Jifty's etc/config.yml to switch the Driver from Pg to SQLite. After trying to install the schema with perl bin/jifty schema --install, I receive the errors:
WARN - DBD::SQLite::db prepare failed: no such table: _db_version(1) at dbdimp.c line 268 at bin/../../Jifty/deps/Jifty/DBI/Handle.pm line 419.
WARN - Jifty::Handle=HASH(0x10d66050) couldn't prepare the query 'SELECT major, minor, rev FROM _db_version'no such table: _db_version(1) at dbdimp.c line 268
INFO - Generating SQL for application Wifty...
WARN - Couldn't require Wifty::Model::Revision : Base class package "Wifty::Record" is empty.
(Perhaps you need to 'use' the module which defines that package first.)
at lib/Wifty/Model/Revision.pm line 15
BEGIN failed--compilation aborted at lib/Wifty/Model/Revision.pm line 15.
Compilation failed in require at (eval 98) line 3.
at bin/../../Jifty/lib/Jifty/Script/Schema.pm line 111
I don't have a Wifty::Record module in my tarball.
Answer
These days, Jifty defaults to SQLite instead of PostgreSQL.
Wifty, however, defaults to the way we run it for Jifty.org. (Perhaps this should change.) Edit etc/config.yml and change the Database Driver from Pg to SQLite.
A big part of what Jifty provides to you is generic hooks for your baseclasses, so the the following virtual classes all inherit from their Jifty equivalents
YourApp::Record ISA Jifty::Record (which ISA Jifty::DBI::Record)
YourApp::Collection ISA Jifty::Collection (which ISA Jifty::DBI::Collection)
Use Template::Toolkit instead of Mason?
Question
Wow, there are a lot of occurrences of the word Mason in the Jifty source code.
Answer
You do an awful lot of hacking. Part of the Jifty philosophy is that we provide (at least) one well integrated way to do everything you need to do. We're big fans of HTML::Mason - it's the templating toolkit that best fits with our model of things - so it's the toolkit that's well integrated into Jifty. We'd love to hear suggestions about how to get TT or other templating engines to support the bits we need.
Make my own testing framework?
Rails has a concept of "fixtures" that get auto-inserted into the database during testing. Can I do that in Jifty?
Sure. You need to make MyApp::Test and use that instead of Jifty::Test in your test files. Here's a sample MyApp::Test:
package MyApp::Test;
use base qw/Jifty::Test/;
sub setup {
my $class = shift;
$class->SUPER::setup;
my $ADMIN = MyApp::CurrentUser->superuser;
my $widget = MyApp::Model::Thingy->new(current_user => $ADMIN);
$widget->create(
foo => "bar",
baz => "troz",
);
# And so on..
}
# You can also override some configuration settings:
sub test_config {
# Customize the config file for testing
my $class = shift;
my ($config) = @_;
my $hash = $class->SUPER::test_Config($config);
$hash->{framework}{LogConfig} = "some/log4perl.conf";
return $hash;
}
Force users to login
Question
Certain portions of my app should only be accessible to users who have logged in. How do I enforce that?
Answer
XXX: this answer is still under construction
(you don't need to use an autohandler for this, you could do it in the dispatcher now)
In the top-level autohandler:
if (not Jifty->web->current_user->id and $m->request_comp->path !~
m{^/(?:public|bits|like|login|css|js|images|__jifty)} ) {
# Not logged in, trying to access a protected page;
# Tangent to the login path.
Jifty->web->tangent(url => '/login/');
} else {
# Public page. Carry on as usual.
$m->call_next;
}
In the login element:
<%init>
# Assumes you have a YourApp::Action::Login
my $action = Jifty->web->new_action(class => 'Login', moniker => 'loginbox' );
# We should have a continuation, if we came here from the autohandler. Otherwise,
# we make a continuation with some sane default request (like for the main page, below)
my $next = Jifty->web->request->continuation
|| Jifty::Continuation->new(request => Jifty::Request->new(path => "/some-main-protected-page"));
# Now, in the form, we set it so that that continuation is called if all of the actions go off:
</%init>
<% Jifty->web->form->start(call => $next) %>
<% $action->form_field('address') %>
<% $action->form_field('password') %>
<% Jifty->web->form->submit(label => 'Login') %>
<% Jifty->web->form->end %>
Create a radio button?
Question
In the Jifty::Manual::Tutorial, there are examples for text boxes and textareas. How do I make a radio button?
Answer
In the same file (e.g. MyBlog/lib/MyApp/Model/Post.pm for a 'Post' model in your 'MyBlog' app) as your other columns, add one like so:
column radioband =>
label is 'Radio Band',
render_as 'Radio',
valid_values ['CB','FM','AM'],
default 'FM';
Then update your database as usual (e.g. increment your version and jifty schema --setup).