Things I Learn While Working with Mojolicious

To download image using UserAgent

use Mojo::UserAgent;
my $ua = Mojo::UserAgent->new;
$ua->max_redirects(5)->get('http://i.imgur.com/lfipl15.jpg')
    ->res->content->asset->move_to('public/temp/image.jpg');

To update all the rows using search

my $temp_my_saved_ads = $self->db->resultset('Favorite')->search({'user_id'=>$self->current_user->id});
$temp_my_saved_ads->update({temp_id => 'aaa'});

Using AS in DBIx::Class is tricky. If you use as in select then you wont get that in get_column(). you have to use AS

my $users = $self->db->resultset('User')->search({
    'items.status_id' => $live
  },
  {
    select => ['me.id as id1', 'count(items.id) as num_ads1', 'me.email as email1', 'me.phone as phone1'],
    as => ['id', 'num_ads', 'email', 'phone'],
    join => 'items',
    group_by =>[qw/me.id/],
    having => "count(items.id) > 4",
    rows => 1,
    order_by => { -asc => 'num_ads1' },
  }
);

Now you can get id using get_column(‘id’).

To get access to request data of the current transaction, you can call the req method on the controller object via

my $request_object = $self->req;

To access POST data

my $name = $self->req->body_params->param('name'); 

To access multiple POST data with same name

my @names = $self->req->body_params->param('name');

To access GET data

my $name = $self->req->query_params->param('name'); 

To access multiple GET data with same name

my @names = $self->req->query_params->param('name');

Suppose you have a table name item_watch_lists. So you controller name would be MyApp::ItemWatchList . Now to Make the routing work you have to define routing like the following or you will get error like Class “MyApp::Itemwatchlist” is not a controller.

my $r = $self->routes;
$sup->get('/user_watchlist')->to('item_watch_list#user_watchlist')->name('watchlist.user');

You also have to create a folder ‘item_watch_list’ for views.

Different way to Loop through DBIx::Class object

my $items = $self->_app->db->resultset('Item')->search({
      published => { 
        between =>  [DateTime->today->subtract(days=> 21)->ymd, DateTime->today->subtract(days=> 20)->ymd]
      },
      status_id => { '=', 6}
  },
  {
    select => [qw/me.id me.owner_id/],
    join => 'pictures',
    group_by =>[qw/me.id me.owner_id/],
    having => "count(pictures.id) < 2",
  }
);
print Dumper $items->count; #it will work
foreach my $item ($items->all){
 print Dumper $item;
}

my @items = $self->_app->db->resultset('Item')->search({
   status_id => { '=', 6}
});
print Dumper $items->count; #it will not work
foreach my $item (@items){
 print Dumper $item;
}

DBIx::Class is wonderful tool but it takes time to get used to it. Here is sql I tried to do it in DBIx::Class. It took me whole day.

SELECT Item.RD, COUNT(Item.key ) AS value 
FROM (
	SELECT DATE( date ) AS RD, me.key 
	FROM reports me WHERE ( ( ( date BETWEEN '2013-05-10 00:00:00+0600' AND '2013-05-11 00:00:00+0600' ) AND report_name_id = 1 ) ) 
	GROUP BY RD, key
	) Item
GROUP BY Item.RD

  my $rs = $self->db->resultset('Report')->search(
  {
    report_name_id  =>  {'=', 1} ,
    date => {  -between => [$start, $end]   },
  },  
  {
    select  =>  [{date => 'date', -as => 'RD' }, 'key'],
    group_by  => [qw/RD key/],
  }
);

$self->db->resultset('Report')->search({},
    {
      select  =>  ['Item.RD', {count => 'Item.key', -as => 'value'}],
      from => [{'Item'=>$rs->as_query}] ,
      group_by  => [qw/Item.RD/],
    }
  );

Here I first built the inner query then I add that query to outer query by using as_query. You have to alias the inner query otherwise you will see “error in from must have an alias”.

use a configaration file while running morbo

export MOJO_CONFIG=bazaar.mobile.conf 
morbo -l 'http://*:3002' ./script/bazaar

To get absolute url

 
my $self = shift;
$self->url_for('/')->to_abs;

Set page title from controller

$self->title('Jambur');

in template

<title>[% h.title || 'CellBazaar &ndash; Market In Your Pocket' %]</title>

Change inactivity timer which is 15 secs by default

Mojo::IOLoop->stream($self->tx->connection)->timeout(300);

To force morbo to listen different port

morbo -l 'http://*:3001' ./script/awsomeapp

If you are using DBIx::Class then it will be great if you can see the SQL statements.

DBIC_TRACE=1 morbo ./script/awsomeapp 

Use Data::Dumper print out variables

use Data::Dumper; 
print Dumper($variable);

Or you can use $self->dumper

print $self->dumper($self->renderer);

in a template you can use

[% h.dumper(variable) %]

Locale::Maketext supports quantification so we can always get the correct sentence:

[% c.l('You have [quant,_1,unpublished ad,unpublished ads]. 
If you would like to publish the [numerate,_1,ad,ads], 
please check under "Ads" below.', new_items_count)%]

See here for other commands: https://metacpan.org/module/Locale::Maketext#Utility-Methods (although quant and numerate is the most useful ones).

Another little tip for starting the dev server:

 
morbo ./script/awsomeapp -w ..

That will make it reload when you change files in the other modules

About Zakir Hyder

This entry was written by .

28. April 2013 by Zakir Hyder
Categories: Mojolicious, Perl | Tags: , , , | Comments

Comments

  1. […] After my git nightmare, I decided to make post like Things I Learn. […]