Skip to content

Latest commit

 

History

History
218 lines (146 loc) · 5.75 KB

Using-DBIC-with-Dancer.pod

File metadata and controls

218 lines (146 loc) · 5.75 KB

Using DBIx::Class within a Dancer application

DBIx::Class, also known as DBIC, is one of the many Perl ORM (Object Relational Mapper), but it's commonly recognized as the best and most widely used.

This is a nice presentation from Leo : http://www.slideshare.net/ranguard/dbixclass-beginners-presentation

Basically, DBIC allows you to interact with your SQL Database without writing any SQL.

To do that, you need a set of Schema classes that describes your database structure. Then you can use DBIC to create, update, delete, search, and do many more things on the data that are in your database.

From a Dancer web application, it is very easy to use DBIC, thanks to Dancer::Plugin::DBIC. This article will implement a simple web application to demonstrate the use of Dancer::Plugin::DBIC.

Simple example

Let's consider a simple Dancer application that allows to search for authors or books. The application is connected to a database, that contains authors, and their books. The website will have one single page with a form, to query books or authors, and display the result.

To keep this article short, the HTML will be simplistic, and the implementation will be a bit stupid. However, I'll try to explain how to properly use Dancer::Plugin::DBIC.

The application will be structured as follow:

  • a Dancer route /search to handle the request, and decide if there is any search to perform, and send the results to the view

  • a view, that will display the search form, and the results if any.

  • a set of models, linked to a database, that will contain the books and authors. These models will be created using DBIC

The basics

Create the application

Okay, that's easy enough:

$> dancer -a bookstore

Change template type

We'll want to loop on results and display authors and books, and it's easier to use Template Toolkit to do that, rather than the default Dancer::Template::Simple.

So let's specify in the configuration that we'll use Template Toolkit as template engine:

# add in bookstore/config.yml
template: template_toolkit

Create a view

We need a view to display the search form, and below, the results, if any. The results will be fed by the route to the view as an arrayref of results. Each result is a hashref, with a author key containing the name of the author, and a books key containing an arrayref of strings : the books names.

That explanation is probably hard to follow, so here is an example, much easier:

# example of a list of results
[ { author => 'author 1',
    books => [ 'book 1', 'book 2' ],
  },
  { author => 'author 2',
    books => [ 'book 3', 'book 4' ],
  }
]

So, what will look the view like? Here is a simple example, displaying the search form, and the results, if any. It's written in Template Toolkit, except that Dancer changes the [‰ %] format to be <% %> instead.

# bookstore/views/search.tt
<p>
<form action="/search">
Search query: <input type="text" name="query" />
</form>
</p>
<br>  

<% IF query.length %>
  <p>Search query was : <% query %>.</p>
  <% IF results.size %>
    Results:
    <ul>
    <% FOREACH result IN results %>
      <li>Author: <% result.author %>
      <ul>
      <% FOREACH book IN result.books %>
        <li><% book %>
      <% END %>
      </ul>
    <% END %>
  <% ELSE %>
    No result
  <% END %>
<% END %>

Create a route

Let's create a simple Dancer route, to be added in the bookstore.pm module:

# add in bookstore/lib/bookstore.pm
get '/search' => sub {
    my $query = params->{query};
    my @results = ();
    if (length $query) {
        @results = _perform_search($query);
    }
    template 'search', { query => $query,
                         results => \@results,
                       };
};

It's rather simple: get the parameter called query, if it exists perform the search, and in any case, call the search view.

So, as you can see, we need to write the _perform_search() method. But before we do that, let's create the database

Create a database

I'll go with SQLite, as it fits well with the aim of simplicity of this example. Let's create the SQLite file database:

$> sqlite3 bookstore.db
CREATE TABLE author( 
  id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
  firstname text default '' not null, 
  lastname text not null);

CREATE TABLE books(
  id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
  author_id INTEGER REFERENCES author (id), 
  title text default '' not null );

Simple stuff: we have 2 tables, one for authors, and one for books, that points to the author table.

Populate with some data

Ian M. Banks

Richard Matheson

Frank Herbert

Use DBIC

Instead of interacting with the database using SQL, let's configure DBIX::Class. DBIC needs to understand how your data are organized in your database. There are two ways of letting DBIC know:

  • either by writing a set of Perl modules, called schema modules: they will describe the database schema, each module describing one entity,

  • or by letting DBIC connect to the database, explore it, and generate the schema itself.

I'll demonstrate the use of the two solutions. I'm personally not a big fan of the detection method: on complex database, it doesn't get everything right, so one needs to help DBIC. I prefer describing the schema manually. But hey, TIMTOWTDI.

that will describe the


There are two ways of using DBIC. FirstDBIC needs a schema

We also need a view:

# 

Let's add a route:

# add in bookstore/lib/bookstore.pm

But

way of writing the web application code



It's
=head1 SEE ALSO

AUTHOR

dams: Damien Krotkine <dams@zarb.org>

POD ERRORS

Hey! The above document had some coding errors, which are explained below:

Around line 91:

Non-ASCII character seen before =encoding in 'C<[‰'. Assuming UTF-8