[Catalyst] Where should constraints go
Where should the various constraint values go in my MVC structure? For example the Model defines the size of each field in (for example) a username field in the User database table as being 16 characters max. I am using FormValidator to validate the username field by calling a validation routine in the Model-User as you can see in the code snippets below. In the example of the username, the constraints are in the length (no more than 16 characters) and in the 'existing' to ensure that a username is not chosen that already exists. This seems to make sense to me since it is the Model that knows the constraints of the database. If I were to do other (business logic) type constraints then I would probably put in a business logic layer where these constraints were defined. The problem is in the View. To give a text error message that 'Must be between 1 and 16 characters' is hard-coding a constraint directly in the view which would need to be changed if the database schema changed. I cannot think of a 'clean' way of getting these database constraints from the Model into the View. Anybody else tackled this issue? Regards Ian The Database has a constraint. CREATE TABLE user ( id int(11) NOT NULL auto_increment, firstname varchar(32), lastnamevarchar(32), usernamevarchar(16), ... In my FormValidator I have something like. constraint_methods => { user_username => [ { name=> 'length', constraint => MyApp::Schema::User::validate_username_length(), }, { name=> 'existing', constraint => MyApp::Schema::User::validate_username_existing($c, $user), }, ], The input form using TT is something like. Username name="user_username" value="[% user.username %]"> [% IF missing.user_username %] Must not be blank [% ELSIF invalid.user_username.length %] Must be between 1 and 16 characters [% ELSIF invalid.user_username.existing %] Sorry, that username is already taken [% END %] ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Where should constraints go
Carl Franks wrote: I made on very basic start [1] on being able to automatically create constraints from the database column types. At the moment it only supports mysql, and it's also probably very out-of-sync with the current svn trunk - but I'd /really/ like to see it finished, and I /really/ don't have any time to work on it, so if you want to take a look and do something with it, that'd be great. My primary goal was to get it working with HTML::Widget as H-W-Constraint-DBIC [2], but there's no reason it couldn't be integrated with any other validation package. [1] http://dev.catalyst.perl.org/repos/bast/branches/DBIx-Class/columns_info_for [2] http://dev.catalystframework.org/repos/Catalyst/trunk/HTML-Widget-Constraint-DBIC/ Carl Carl Creating the constraints is not really the problem. Your approach certainly helps and one that any ORM should include. I can see that it would take a fair amount of work to cover all bases. For example, if a constraint was put on a DATE field such that it could not be later than NOW and no earlier than NOW - 20 Days. (for example). Putting these sort of constraints is the duty of either the database level (where they naturally go anyway) or perhaps in the business logic layer. My problem is finding a clean way of getting these constraints out of the Model and into the View so that I can generate meaningful error messages without hard-coding them in the templates. By 'clean' I mean not having to code the Controller to act as the middle-man and just pass them from the Model to the View. Perhaps I am expecting too much. ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Where should constraints go
Yes this pretty much agrees with my interpretation. It is not so much the location of the constraint rules as how to propagate them to the view (i.e the stash) John Siracusa wrote: Keep in mind that there are at least three possible levels of constraints in a database-backed web app. 1. Constraints enforced by the database (e.g., maximum length for a varchar column) 2. The constraints of your object model (e.g., alpha-numeric characters only in usernames) 3. Application constraints (e.g., usernames that begin with "acme_" may not be registered using the public web site) That's all for one piece of information: a username. Database constraints apply "everywhere." Object model constraints also might apply everywhere, by you may want to bend the rules for some special cases. (If an object model constraint really does apply everywhere, it should probably be moved to the database, if possible.) Application constraints are almost certain to change (e.g., internal admin tools usually have fewer such constraints than public end-user tools). If you try to smoosh up all three of these kinds of constraints into a single definition, much pain awaits you :) My preferred distribution of responsibilities is: 1. Database constraints: defined in the database, and also reflected (as much as possible) in the ORM-based classes. 2. Object model constraints: defined either in the ORM-based classes or in classes that wrap them (if such things exist). 3. Application constraints: defined in form/field objects, which may inspect the ORM constraints and use them as a starting point. -John ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/ ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Where should constraints go
Brian Kirkbride wrote: ... This is the approach I have taken in the past, although I hadn't included any metadata (ie [1,16]) with the error_id. This fits into separation of business and presentation logic nicely because the model is free to return an error that has some semantic meaning "PASSWORD_TOO_SHORT", but the view is free to say "Enter a longer password you submoron, you!" if need be. For my Catalyst apps, I can either do something like: [% c.format_error(error_id) %] or [% error_messages.$error_id %] or even [% error_messages.${lang}.${error_id} %] to map the model-specified error to a presentable string for the view. I prefer the first, but it does clutter the Application Context namespace somewhat. Best, Brian Kirkbride This is pretty much what I do via the FormValidator. I convert the 'missing' or the 'invalid' messages that it produces into the flags [% missing.user_username %] and [% invalid.user_username.length %] which then result in the error messages being produced. I still need to give some thought to internationalisation, but that is another question. :) ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Where should constraints go
Matt S Trout wrote: Ian Docherty wrote: My problem is finding a clean way of getting these constraints out of the Model and into the View so that I can generate meaningful error messages without hard-coding them in the templates. By 'clean' I mean not having to code the Controller to act as the middle-man and just pass them from the Model to the View. Perhaps I am expecting too much. No, I understand entirely, and you aren't expecting too much at all - except perhaps any expectation that this would already be fully implemented :) We're doing this in Reaction using Moose to provide an introspectable metamodel so the update action class reflects its constraints off the model and then the form reflects its field types off the update action and the fields just have the constraints "already there" when they're doing validation. It's been hard work and there's a lot of hard work still to come but so far it works bloody well. How the hell do you find the time to work on Catalyst and on Reaction at the same time!!! One thing occurs to me. What I want to do is to get parameters from the Model (or the Business layer) into the View via the stash. So for a User object I want be able to do something like. Username must be between [% schema.user.username.min %] and [% schema.user.username.max %] characters The only problem now is how to get this information from the DBIC data in a DRY manner. My model namespace is not in Catalyst as in:- MyApp::Model::DBIC::User but is in MyApp::Schema::User so that I can use it outside my Catalyst application (for example in cron jobs) so I don't have a mechanism to do something like. $c->forward->('MyApp::Model::DBIC::User/constraints') Where 'constraints' would populate the stash with all the constraints for the User table. The only option I can see is to do a call everywhere that I need constraints as follows. $c->stash->{schema}{user} = MyApp::Model::DBIC::User::Constraints(); And in there do the following. sub Constraints { return { username => { min => 0, max => 16, }, firstname => { min => 0, max => 32, }, }; } Carl Franks has proposed a method using 'columns_info_for' which I will have to give some more thought to and this may remove my worry that by doing the above I am not doing it in a DRY manner. ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
[Catalyst] Localization (was - Where should constraints go)
John Siracusa wrote: ...cut... Warning! Localization alert! :) Like I said before, I don't think you really want to be passing things to the view at that granularity. It makes for some vary hairy form templates--one for each locale, to boot. If you whip up all this stuff *before* passing it off to the template, you get templates like this (shown using Mason with a "designer-friendly" syntax for the form/fields which just translates deterministically into the corresponding method calls at runtime): <% '/messages.mc', %ARGS %> <% 'START_FORM' |fm %> <% 'USERNAME:LABEL' |f %> <% 'USERNAME:FIELD' |f %> <% 'PASSWORD:LABEL' |f %> <% 'PASSWORD:FIELD' |f %> <% 'LOGIN_BUTTON:FIELD' |f %> <% 'END_FORM' |fm %> That's one form template for all supported languages, complete with extremely granular, localized error messages. (e.g., "The username 'whatever' is already taken. Please choose another.") The form-wide messages go in the message box produced (or not, if no messages) at the top by messages.mc. The per-field errors are returned by the "USERNAME:FIELD" calls and go under each field. Even ignoring localization, you will save much sanity by constructing all this stuff "perl-side" before passing it off to a template. -John This all makes excellent sense, since localisation is another thing to worry about on my agenda! Leaving aside my original question, I do however have the following observations. 1) The contents of USERNAME:LABEL and USERNAME:FIELD have to be created somewhere. I assume that this is in the controller, which creates some HTML (using widgets or the like) and which inserts the localised text? 2) I don't like the idea of there being *any* html code produced in the controller since in principle the same controller could be used for different output media. 3) ISTM that there should be another layer between the controller and the Template to perform the localisation. Perhaps this is where the View needs to actually have code rather than taking the passive approach that I see in all the Catalyst examples. So the controller would generate some generic error flag (e.g. a flag to warn that the username field is already taken, or is too long) and the localisation 'layer' would convert this into the appropriate language version. ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Where should constraints go
Laurent Thank you for that information. I will certainly look at Data::Domain in some detail. I don't know if I will move over to it since I have already invested a lot of time and effort into using Data::FormValidator but I will certainly look at it for my next project. :) Regards Ian C. Docherty (Icydee) Hi Ian, I am currently looking at this issue for a big intranet application where we have many business rules to validate. As you say, rules interfere both with models and views, and it would be nice to avoid duplicating the information. Now where should rules live ? Deriving rules from the database, as Carl suggested in this thread, is an excellent start, but it is not enough : there might be many things that a database cannot express, like regular expressions, contextual dependencies, or your example of date boundaries depending on the current date. On the other hand, form validation packages are often too much focused on the view and also fail to express the complex rules just mentioned. The general problem is that the range of possible rules is very wide : some rules are quite simple, and for those we would like a short declarative language to express them, while other rules definitely need some computing power that goes beyond a declarative language. So I tried to address this in Data::Domain, which was published on CPAN just 2 weeks ago. This module is designed for providing a compact way to express complex constraints about structured data (including lazy constraints that may inspect the surrounding context). It then generates a structured set of error messages that can be fed to the view, either server-side through Template Toolkit, or client-side through Ajax methods. Messages are either auto-generated or can be redefined by client code (for example for internalization). The general scenario is that you get structured data by piping the parameters of your HTML form through CGI::Expand; then you validate the whole tree, and get back a tree of error messages that can be mapped back to the form fields. You may also want to have a look at Declare::Constraints::Simple, which addresses the same problem and has some similarities in design. Best regards, L. Dami ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
[Catalyst] Ideas on localisation
I have been investigation options for localisation and it occurs to me to use something like Catalyst::Plugin::I18N My understanding of this package is that you create a language package for each language you want to support. e.g. MyApp::I18N::de MyApp::I18N::fr etc. However, this seems to lump together all the text for all the pages into one file. This would seem to have two problems. 1) Each language is a huge file containing all the text for all pages of the application lumped all together. Managing this one file becomes difficult. 2) We have to load all the text for all the pages at once. This is like loading every template in the system just to display one page. Would it not make more sense to have a structure that more closely follows the hierarchy of either the root directory or the controller hierarchy. e.g. MyApp::I18N::User::List::de MyApp::I18N::User::List::fr MyApp::I18N::User::Edit::de MyApp::I18N::User::Edit::fr MyApp::I18N::User::View::de MyApp::I18N::User::View::fr etc. Alternatively (and this is an option I prefer) have a way of loading the language text from a database. I would then load all text from the database that matched the URI 'user/list' (and any common text such as header and footer text) and make that available to the I18N module. Has anyone done anything like this in the past? Regards Ian C.Docherty (IcyDee) ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] automatic form generation based on data models
marcus baker wrote: In a primarily Perl shop I've joined, Django has become all the rage. Everyone into it is amazed at the templating capabilities and the database abstraction layer (...they obviously hadn't really done much with the Template Toolkit, or even heard of Class::DBI or DBIx::Class). Django's all fine and lovely, but personally I still prefer Catalyst due to the vastness of the CPAN library I can use behind it. The one thing about Django that keeps them from looking anywhere else is it's ability to create data-editing forms on the fly based on the data model. In an attempt to get them to consider Catalyst a little more, I was wondering if Catalyst has this kind of capability anywhere... Is this something I should take to the CDBI/DBIxC lists specifically? Thanks -Marcus I just don't understand why everyone seems to wet their pants over something that 'creates data-editing forms' directly from the data model! As a demo application, or a simple proof of concept that it always looks impressive when you can create these forms and update a few tables with a few lines of code. Anyone who has written big web applications knows however that it is never that simple and so the few (hours/days) that can be saved in the early stages of coding are nothing compared to the (weeks/months) of coding for a 'real' application. At the end of the day it is the additional help that something like CPAN gives you combined with something like Catalyst that gives the productivity. Regards Ian ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] automatic form generation based on data models
Josef Karthauser wrote: On Wed, Nov 08, 2006 at 10:29:11PM +0100, Zbigniew Lukasiak wrote: ... I agree. I'm a week (part time) into building my application with Cayalyst, and I'm still not anywhere near the functionality I had with Maypole after a day of hacking. This isn't because maypole is more powerful or anything, no as far as I can see Cataylst is far more mature. But without a decent CRUD tutorial at least, it's been a steep learning curve. Joe Perhaps that is the point, the learning curve. I find that having used Catalyst for a year there is less of a learning curve and I don't even bother to use the helpers to create my methods. I just create them by hand. However when starting to learn Catalyst a CRUD may be of used (until experience is gained). Regards Ian ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
[Catalyst] Announce. Catalyst::Plugin::I18N::DBIC 0.01
Since I got no response to my request a few weeks ago about I18N data from a database I wrote my own :) This module has just been released to CPAN. It builds on Catalyst::Plugin::I18N and inherits all methods from that module. In addition it provides a 'load_lexicon' method that loads data from a database. (Which reminds me, the POD does not explain the database structure ;( I see version 0.02 coming on...) The 'Lexicon' data in the en.pm, fr.pm, de.pm etc. files is empty. It is loaded from the database using the 'load_lexicon' method. You can also divide up your application into 'paths', for example 'header', 'footer', 'navigation', 'user/edit', 'user/login' etc. which means you only need to load a subset of the translation data as required by your templates. Regards Ian C. Docherty (ICD) ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Announce. Catalyst::Plugin::I18N::DBIC 0.01
John I finally worked out what I was doing wrong in my upload to CPAN. It should be on the mirrors soon, but if you want a version prior to that or information on how to use it send me a personal email. Regards Ian John Napiorkowski wrote: I'll be using it in this application I wrote that stores the TT templates in a database. Now I can move everything to the DB interface for my users. Thanks! --john ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] IDE/editor
Have you looked at UltraEdit for Windows (unfortunately no version for Linux) http://www.ultraedit.com/ I think it gives you everything you listed and more. Regards Ian Docherty Christopher H. Laco wrote: Max Afonov wrote: Now the funny part is that you did NOT recommend Eclipse after all! I'm really really picky about my editors. I've used Textpad on Windows forever, and recently SCite. What I look for in an editor is that the toolbar is slim, but I have a lot of options under hood. For me, those "options" have to be the ability to change these things per file type: syntax coloring tab/space stop/size default encoding (UTF8, UTF16, OEM, Latin) default endings (LF, CRLF, CR) write/or not write the BOM (Byte Order Marker) This last 3 always seemed to trip me up in Eclipse/EPIC inthe early 3.0 days...and of course, Eclipse was always slow for me.. compared to Textpad/Scite. Back when I owned a working mac (91-96), I was BBEdit all the way. And when I get my next Mac, I'm sure I'll be all about TextMate. -=Chris ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Announce. Catalyst::Plugin::I18N::DBIC 0.01
Brandon. Thanks for the feedback. see below. Brandon Black wrote: snip... I've just been looking at Cat I18N stuff. This looks promising (I haven't actually used it yet). Based on the source, I would make a few suggestions for the next version: 1) Make the model name "DBIC::Lexicon" configurable instead of hardcoded, via config->{'I18N::DBIC'}->lexicon_model Since I am extending existing packages that already hard-code the name 'Lexicon' I don't see that this can be changed easily. 2) Why not make the primary key (language, path, message) instead of a random incrementing serial numer that isn't used? It would help reduce accidental redundancy in the database, and give you an index on the columns most likely to be searched on. Certainly, as I think I mention in the docs, the index can be anything you want and is not required by the module. So by all means set up your index in this way, the schema was just one example. 3) Reloading lexicons per-request is going to be wasteful in the most common cases. It might be better to offer a couple of other options (via configuration), such as: a) Pre-load the entire Lexicon at app startup b) Dynamically load lexicon paths into memory as they are used, but cache them from then on (don't reload unnecessarily) Those are well worth doing. I presume that you are talking about mod-perl in this case so that the lexicon data is cached between requests. I will look to do this in a new release. Thanks for your feedback. Regards Ian C. Docherty (ICD) ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Announce. Catalyst::Plugin::I18N::DBIC 0.01
Ian Docherty wrote: Brandon. Thanks for the feedback. see below. Brandon Black wrote: snip... I've just been looking at Cat I18N stuff. This looks promising (I haven't actually used it yet). Based on the source, I would make a few suggestions for the next version: 1) Make the model name "DBIC::Lexicon" configurable instead of hardcoded, via config->{'I18N::DBIC'}->lexicon_model Just re-read this. I must have been too tired this morning to understand. I see now. Yes, the Model name should be configurable. Thanks. Regards Ian C. Docherty (ICD) ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Announce. Catalyst::Plugin::I18N::DBIC 0.01
Daniel We are still at an early stage in terms of learning how to provide i18n and I produced this module as much as a 'proof of concept' as anything else. I would be very interested in discussing what you have been doing but it may be best to move the discussion out of this forum unless it is specific about Catalyst. Do you, or anyone else interested in this discussion, want to reply to me directly? As you say, the plugin to get information from the database is easy. What is difficult is the way that the data in the schema is maintained and updated and how translation is managed etc. I presume that this is what you are referring to. I anticipate creating a mini-app that will allow a translator to make changes to the database code and view the result immediately in the application. Regards Ian C. Docherty (ICD) Daniel McBrearty wrote: I'm sorry I didn't see this earlier. We also have translated text stored in the db, and have evolved a schema to cope with that. We are not using the cat->i18n plugin at the moment though - we wrote our own to use our schema. At some point though we'd like to share some of the stuff that we've learned and use the communal code where possible. I'd be interested to see the schema and see how it compares with what we are doing. This was the area that I found trickiest - the plugin to grap stuff out of the schema is realatively easy. ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
[Catalyst] Cannot create a cache
I am trying to implement a cache with a Catalyst app running under Apache2 mod-perl and as far as I can tell the cache is clear at the start of each request. I have a hash which is acting as my cache but even if I put values into it, on the next request the hash is empty. Have I configured my Apache2 config file correctly for Catalyst or am I missing something more basic? Regards Ian C. Docherty (ICD) ### package Catalyst::Plugin::MyPlugin; use vars qw (%cached); My apache2 config is as follows. NameVirtualHost *:8000 use lib qw(/var/sandbox/myapp/lib); PerlModule Horivert::MyApp ServerName sprint.mydomain.com ErrorLog /var/sandbox/myapp/error_log Alias /static/ "/var/sandbox/myapp/root/static/" SetHandler modperl PerlResponseHandler Horivert::MyApp ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Cannot create a cache
Perrin Harkins wrote: Ian Docherty wrote: I have a hash which is acting as my cache but even if I put values into it, on the next request the hash is empty. Are you aware that apache runs multiple processes and that each process has a different copy of your %cache variable? You will not get the same process each time. If you want to share between processes, you need something like Cache::FastMmap. - Perrin Perrin Excellent. Thanks for pointing that out to me. Yes I should have thought of that point but it was eluding me. I just *knew* that it was something pretty fundamental! Regards Ian C. Docherty (ICD) ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
[Catalyst] Coverage tests in Catalyst
Is it possible to do coverage tests in a Catalyst application? If so how? I can't find any references that help. ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Coverage tests in Catalyst
Don't we have to do both of these? Coverage of the 'make test' will only show coverage for those modules we can test 'statically' i.e. by making direct calls to the methods in the tests Tests that are done with LWP (or is it Mechanize) which are http requests to the application will probably be the bulk of the tests for a big application and these will not be caught by the first method but will by the second. I suppose I am asking if both these can be combined to give total coverage from the two techniques. Jonathan Rockway wrote: Ian Docherty wrote: Is it possible to do coverage tests in a Catalyst application? If so how? I can't find any references that help. Catalyst apps aren't special -- do coverage tests like you would with any other perl module: $ cover -delete $ HARNESS_PERL_SWITCHES=-MDevel::Cover make test $ cover If you want "coverage" and not test coverage (why?), then just do $ perl -MDevel::Cover myapp_server.pl $ cover Regards, Jonathan Rockway ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
[Catalyst] using 'config' in a partpath
if I want a URI like /config/34/display Then I can create a PartPath similar to:- package MyApp::Controller::Config; use strict; use warnings; use base 'Catalyst::Controller'; sub Config : PartPath('/config') Chained('/') CaptureArgs(1) { my ($self, $c, $config_id) = @_; # do something } But actually I can't, because this example gives me a URI of /Config/32/display (note the uppercase 'C') because if I try to use lowercase 'config' it conflicts with Catalyst::Controller::config Any ideas on how I can have a lower-case 'config/32/xxx' in my PartPath? Regards IcyDee ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] using 'config' in a partpath
Ash Berlin wrote: By using PathPart instead ;) Ouch. I even looked at your answer for a while before realizing there was a difference between PathPart and PartPath =-O Thanks greatly. That (and Robert 'phaylon' Sedlacek's answer) put me back on the correct path. Regards Ian ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
[Catalyst] Browser window/tab independent sessions
Does anyone try to keep different state information in different browser windows/tabs? For example, it makes sense to have a session variable that holds the currently logged in user. This will be available to any browser window that is open to the application. But what if you wanted to keep some state information dependent on the browser window. So for example you could have multiple windows open, each one in a different state of (for example) setting up a money transfer. The user could move between different windows at will, completing one form or not etc. and setting state in one would not affect the others. I think that I have in mind a RESTful application, but not exactly. I find it very useful for example to hold search filter data in a session variable. Then when I come back to that form the search filters hold the previous search values. In a complex application there could be many of these variables. Now in a multi-window browser it would probably be good to make each of these browser windows hold a different state for these search filters. The only idea I have is to hold the browser window session in the URI, e.g. http://mydomain.com/window_session/XYZ/transaction/123/user/456/edit where the /window_session/XYZ part would be a PathPart and would be different for each browser window. How would I create these URI's for each window. I suppose I would have to have a 'create new window' button in the application that generated a new window with a unique window_session? I can't be the first person to try this, what have other people done? Regards Ian Docherty (IcyDee) ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Browser window/tab independent sessions
Hermida, Leandro wrote: The way cookies work for holding application state has the limitation of being for every window/tab of that browser type (someone please correct me if I am wrong). Use Catalyst::Plugin::Session::State::URI to pass the session IDs through the URI but please read the POD on security issues related to this!!! I also had to write an app sometime ago where I didn't use cookies so I just passed the session ID in form hidden fields (for POSTs) and in the URI (for GETs). Then each browser window/tab will have its own independent session no prob.. Leandro I used URI session variables previously where cookies were not available. It occurs to me that if the are being used to have separate sessions for each tab or window then the security issues could be eliminated by making the session a combination of a cookie (fixed for all windows/tabs) and the URI parameter (different for all windows/tabs). I still don't know how to ensure each new window/tab gets it's own unique session in the URI however? Regards Ian Docherty (IcyDee) ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Browser window/tab independent sessions
Octavian Rasnita wrote: Hi, Maybe I didn't understand well the question, but if the user wants to create a session that works only in a certain window, but doesn't work in the other windows, a simple cookie can be used if its expiry date is set to 0. This way the cookie won't be saved, but it will be memorised by the current window of the browser, and if the browser window is closed, the session ID is lost, and the user must log in again for creating another session. Same thing if he wants to use another window. Isn't this what is needed? Octavian No, setting it to 0 just ensures that when the *browser* is closed the cookie is removed. A cookie set in one window is available to all windows of that browser and all windows/tabs have the same cookie (and hence the same session). Regards Ian C. Docherty (IcyDee) ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Browser window/tab independent sessions
Matija Grabnar wrote: Octavian Rasnita wrote: And I think this is what is wanted, because I can't see other needs for having 2 separate sessions on the same computer. There is no need for having two separate sessions if you can guarantee the user will ALWAYS be able to finish one task before starting another. That works beautifully in theory, not so well in real life. Practical case one: database of users for an ISP. A helpdesk operator is going through his tickets, looking up one user at a time, when a phone call comes in. He now either has to deal with the customer without looking them up (practically impossible), or he has to abandon the session where he half completed the processing of the ticket in order to look up the customer. Both alternatives are unappealing. This is exactly the case I am trying to solve. The Helpdesk operator needs to be kept logged in (even if she opens another browser window) but the half completed ticket is retained together with any search terms *for that browser window*. A partial ticket in another window has it's own search terms. This is rather getting off the topic for a 'Catalyst' list. I posted here originally because I wanted to know if there was a Catalyst solution. It looks like the answer is to use cookies for things like user login and use URL encoding for new browser windows so that I can keep state for them separately. What is still not clear is how to generate (for all possible ways of opening a new window) a new URL encoded session value. e.g. cutting and pasting a URL from one window into another will also copy the URL encoded session so both windows would have the same state. There are very good reasons why PART of the session information should be unique to each tab, and PART of it should be common. Deciding which part belongs where requires knowledge of the problem domain, and thinking through of common usage scenarios. Exactly Saying "Oh, that problem is solved by choosing browser X" is completely unacceptable in the real world. In the real world, you can NOT choose which browser all the people using your application will run, nor can you afford to turn away those who run different browsers. ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] number of users
It depends what you mean by 'logged on'. For example, if a user logs into the system, reads a few pages, then goes to an external web site, or even closes their browser, how would you know? What if they come back before their session times out? The only definition that I would think you could use is how many 'live' sessions are there and for this you would have to look at your session store. With Session::Store::File it uses |Cache::FileCache and I can't see any direct way of reading how many sessions are still active. You would have to look at the code I think. |Regards Ian Docherty (IcyDee) Octavian Rasnita wrote: Hi, Is it possible to calculate the number of users logged on at a certain moment? I am using the following Plugins: Session::State::Cookie Session::Store::File Authentication::Store::DBIC Authentication::Credential::Password Authorization::Roles Thanks. Octavian ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/ ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Browser window/tab independent sessions
Perrin Harkins wrote: Ian Docherty wrote: What is still not clear is how to generate (for all possible ways of opening a new window) a new URL encoded session value. e.g. cutting and pasting a URL from one window into another will also copy the URL encoded session so both windows would have the same state. It's not a problem. You have to stop thinking session IDs. If what you have in the URL is things like the current search term, it doesn't hurt anything for them to be there when the person copies the URL and pastes it into a new window. The new window's data will change as the person uses it, with no affect on the old window. The only way it can be a problem is if you put session IDs in the URL that are tied back to server-side state. Then both windows will be trying to change the same server-side state. In other words, for state information that you keep in the URLs, making a new window and pasting the URL into it will instantly split the new window's state from the old one. OK, I see and understand. However, it also depends on the amount of information that has to be stored and there is a limit (but I can't remember what it is) in the length of a URL. I can see I might need to put a lot of information into the URL, for example when generating complex free-form reports based on a form (have you seen the reporting system in RT for example). I think I will have to put this thread in my subconscious and come back to it later :) Regards Ian Docherty (IcyDee) As someone else pointed out, Apache::Session::Counted can also solve this problem, but most people will find it more confusing than just putting everything in the URLs. - Perrin ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Recommend methods for form handling
John Napiorkowski wrote: I think FillInForm is quasi depreciated, since it parses each request and can slow things down quite a bit. I had an initial struggle with FillInForm initially, but then I struggled finding a good alternative in the first place. I am now quite keen on using it and have used it for several large web and intranet sites with no problems. The only issue I had was with checkboxes filled in from the database, since CGI does not send back a value for unchecked checkboxes then FillInForm would not handle them correctly so I had to develop a work-around. Regards Ian Docherty (IcyDee) ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Recommend methods for form handling
Hartmaier Alexander wrote: Hi Jim! I don't recommend the use of FillInForm, I dropped it finally two weeks ago when I had time to refactor my Catalyst apps that used it. Now I handle forms by putting the data they should show on the stash with $c->stash->{form_data}->{fieldname} = 'value'; I have to private actions to do this, one _from_db and one _from_params. Their names should be self-explanatory. E.g. the edit action forwards to the _from_db method on first load of the form which is detected by checking for method POST and the value of the submit button, else the _from_params. With this I don't have to overwrite the cgi params and have full control of what my form should display. Those values are used in my templates like value="[% form_data.fieldname %]". You can look at FormBuilder which should be pretty good from what I've heard. I'll wait for Reaction and invest some time in learning how to use it when it's done. Ah, and I use Plugin::FormValidator for the form validation. A private do_form method does this and is used for both add and edit methods. -Alex I tried this approach myself some time ago, before I moved to FillInForm but I found in cumbersome. I would like to you say what you did not like about FillInForm and why you don't recommend it? The trouble with your _from_db and your _from_params approach (which is similar to the approach I originally used) is that you have to write a long sequence of copies from one place to another and to keep track of all the things you have to copy, adding new ones when you add form elements. It breaks the DRY approach since you now have similar code in at least two or three places. (from the db to the stash, from the params to the stash, from the stash to the db). What I especially like about using FillInForm is that if I have a form that edits (say) a user, I simply pass the user object on the stash. The template then refers to [% user.firstname %], [% user.lastname %] etc. and FillInForm does the rest when the form is re-submitted. It makes my controllers so much simpler. Regards Ian Docherty (IcyDee) ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Recommend methods for form handling
The only issue I had was with checkboxes filled in from the database, since CGI does not send back a value for unchecked checkboxes then FillInForm would not handle them correctly so I had to develop a work-around. Regards Ian Docherty (IcyDee) Oh, amazing! I was just starting to write a post asking something like that, although my problem showed on radiobuttons (e.g. option 0=No doesn't get selected), using Formbuilder, but I think it's the same principle. Would you please show/explain your workaround? In the meanwhile, I just tried using "false" instead of "0" (works for inserting/updating, at least with PostgreSQL) and converting "0" to "false" when filling form, but I don't think it's really elegant... Regards, Juan Juan I have a hidden field in the form 'action' which is true when the form is submitted, but false the first time the form is displayed (from the database). Then for a checkbox (and I assume this could be extended to radio buttons) I do the following in my template. action %]checked[% END %]> So, first time round the 'checked' values depends only on the user.active flag (from the database) on subsequent times round (for example when a form error was found) and 'action' is set then the state of the checkbox is handled by FillInForm. Without the 'and not action' bit if the database had 'user.active' set then if an attempt to uncheck the checkbox was made, and if there was an error on the form elsewhere, FillInForm would not uncheck the box. Regards Ian Docherty (IcyDee) ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Recommend methods for form handling
Jim Spath wrote: Thanks for all the responses guys, they have been very helpful! What about multi-lingual support? It seems like FormBuilder is my "best" choice if I want to add multi-lingual support down the road. - Jim What has FormBuilder got to do with multi-lingual support? I use Catalyst::Plugin::I18N::DBIC (shameless plug) I don't use FormBuilder, I 'roll my own' html which gives me more control. Regards Ian Docherty (IcyDee) ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
[Catalyst] DRY REST
I would welcome some advise on how to organise this. I have several places where I want to create a 'person', by which I mean enter firstname, lastname, birthdate etc. for a person. Now a 'person' can be a sender, a beneficiary, a user, an agent etc. and using inheritance 'person' is a base class. When I create a sender (for example) I would do so at the URI '/transaction/xxx/sender/create' and it could also be done at 'sender/create' the same code could be used in '/transaction/xxx/beneficiary/create' etc. The idea is that where controllers create any 'person' type information I would use common code (a common controller?) to create the form elements and validate the form data (I am using FillInForm and FormValidator). I have seen some documentation in Catalyst::DispatchType:Chained using *:Chained('.')* but I don't really know if that is any help to me. Any other suggestions? Regards Ian (IcyDee) ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Re: looping
A. Pagaltzis wrote: * Will Smith <[EMAIL PROTECTED]> [2007-02-12 21:25]: my $column = $c->model("myDB::Author")->get_column('last_name'); while(my $name = $column->next){ $lname[$i] = $name; $i = $i + 1; } Ugh. Use `push`; this isn’t C. Regards, Or 'map' ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Sharing session and login data
I might be asking the blindingly obvious, but do the two applications use the same domain? If not sessions will not work between them because the session ID is normally stored in a cookie which cannot be passed between domains. You may have to pass the cookie in the URL in that case. Regards Ian (icydee) Tiziano Faion wrote: Hi All, I've got a trouble in sharing data session betweeb two catalyst applications. The First one is an intranet software where user log in. The second one is a production monitoring software. In intranet i've a link that opens, in the same window, the second app. Two apps shares same database for user and roles. Now.. If i login into intranet and i go to the second app. i lose my login and role information. I hoped that setting the same path for session in yaml for both applications would be enough but... Any suggestion? Link? Thanks in advance Tiziano ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] html escaping question
Mario Minati wrote: I am Carl. But how can I circumvent this. Actually it's not a clever question. Is it usefull to circumvent that. My current problem: As the part of my project I am working on at moment deals with companies I have to deal with "GmbH & Co. KG" which is a quite popular type of company in Germany. If a users types that in a form field everything is fine until it comes to editing. The string is escaped - of course. But the user is confused when he sees "GmbH & Co. KG". How to go about that? Greets, Mario Minati Check at which point the escaping is being done. Is it in your database un-escaped for example? Regards Ian C. Docherty (icydee) ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] html escaping question
Mario I might have the wrong end of the stick here but I hope you are saying that you are going to fix this by making sure that the database holds the un-escaped text? Regards Ian C Docherty (icydee) Mario Minati wrote: Am Mittwoch 21 März 2007 15:01 schrieb Carl Franks: You were right, as always ;-) I used the FormFu HTMLEscape Filter and the $amp; in the database got encode a second time while form processing. Thanks again, Mario ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/ ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
[Catalyst] fastcgi configuration problems
I can only see my Catalyst home page using fastcgi, all other pages report a '404 not found'. I have been using Catalyst for about a year using Apache mod-perl or the build-in catalyst server. I now need to run more than one instance of an application on a server. I understand I can do this with fastcgi. Correct me if I am wrong, I should use the standalone/external configuration. This will allow me to start several fastcgi processes and attach to them in my Apache config. I do the following in my application root ./script/timesheet_fastcgi.pl -l /tmp/timesheet.socket -n 2 and my Apache config reads... FastCgiExternalServer /tmp/timesheet.fcgi -socket /tmp/timesheet.socket ServerName timesheet.mydomain.com Alias / /tmp/timesheet.fcgi As I said, this works for my applications home page, but not for any other pages. It works fine using the catalyst server or the Apache config only approach. Regards Ian ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] fastcgi configuration problems
Brian. Excellent, that was it exactly (amazing what difference a single '/' can make!) (That puts pressure on me to recipricate and to update C-P-I18N-DBIC to help you now! I will see what I can do) Regards Ian Brian Cassidy wrote: Ian Docherty wrote: FastCgiExternalServer /tmp/timesheet.fcgi -socket /tmp/timesheet.socket ServerName timesheet.mydomain.com Alias / /tmp/timesheet.fcgi Just for kicks try: Alias / /tmp/timesheet.fcgi/ (note trailing slash) -Brian ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/ ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] fastcgi configuration problems
Wade Thanks for that advise, I will certainly do so. However I was only following the tutorials and installation instructions so perhaps they should be updated as well. Regards Ian C Docherty (icydee) [EMAIL PROTECTED] wrote: rahed <[EMAIL PROTECTED]> wrote on 03/23/2007 10:27:04 AM: ServerName timesheet.mydomain.com Alias / /tmp/timesheet.fcgi I think your Alias should read like this: Alias / /path/to/script/timesheet_fastcgi.pl/ Yes, and to reduce the "ickyness" factor, move /tmp/timesheet.fcgi to a /var/run/timesheet/ directory or some such and lock down the permissions to the appropriate user/groups. Many old time (and even newbie) unix guys dislike using /tmp or /var/tmp for sockets. /var/run is for application/daemon variable runtime files and sockets. http://www.pathname.com/fhs/2.2/fhs-5.13.html and /tmp is for temp files that get deleted on system reboot. http://www.pathname.com/fhs/2.2/fhs-3.15.html -Wade ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/ ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] basic CRUD confusion
Jack Lauritsen wrote: Hello, I am building a (test only) site based modifying the classes in the catalyst tutorial, and have a hopefully simple question. I have a search box that takes an isbn number, and then build a book with the data from amazon web services. The problem comes when I want to update the authors list. I don't have the author id. How do I get the id out of MyAppDB::Author? I tried the following: == foreach my $amazonauthor ($amazonbook->made_by()) { my $author = $c->model('MyAppDB::Author')->search({name => $amazonauthor}); 'search' returns an array, so in scalar context this will put the array size into '$author' not what you want. Use either my ($author) = $c->model('MyAppDB::Author')->search({name => $amazonauthor}); or my $author = $c->model('MyAppDB::Author')->search({name => $amazonauthor})->first; if ($author->{id} != undef) { $author = $c->model('MyAppDB::Author')->search({name => $amazonauthor}); $book->add_to_book_authors({author_id => $author->{id}}); } else { $author = $c->model('MyAppDB::Author')->create({ name => $amazonauthor # yes, my DB has just \id name\ }); $book->add_to_book_authors({author_id => $author->{id}}); } == is the syntax wrong "$author->{id}" I think this should be '$author->id' or have I made the Author incorrectly? thanks in advanced for anyone who can point me in the right direction. Jack. ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Read and Display from i/o file
Will First you need to put the data you read into an array (for example @rows) then put it on the stash The main problem is that your template [% FOREACH row IN row %] should be [% FOREACH row IN rows %] I think this is your main problem. Regards Ian C. Docherty (icydee) Will Smith wrote: Hi, I am using Text::Delimited to read in a text file, that's very straigth forward. My problem is I want to display back onto the template what has been read from the file: my $row = $file->read; # for example the file has 2 col: id, name I cannot do like this on the template: [% FOREACH row IN row %] [% row.id %] and [% row.name %] [% END %] Please someone give me a brief explanation why I could not do that, and how can I display the data on the template. Thank you. ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
[Catalyst] Team needed for Catalyst project work in Eastern Europe?
We are looking for a small team of Catalyst programmers, based in Eastern Europe, who may be interested in a project. The project is to replace an existing PHP/MySql transaction processing web application with a new application written in Catalyst/DBIC Some analysis of the current application is required to reverse engineer it, but the new system will be much more flexible to configure and to expand into other applications. Work has already started on the application but progress is slow due to other commitments so we are looking to start up a dedicated team to complete this work. Anyone who feels they have the commercial experience for this please contact me privately and we can discuss this in more detail. Regards Ian C. Docherty (icydee). ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
[Catalyst] Developers needed for two Catalyst projects
Hi I am the technical director of Horivert Business Solutions in the UK. http://horivert.co.uk We have two catalyst based projects that we need developers for, ideally as a team. One project is already started and uses Catalyst, DBIC, TT and is a money transfer back office system. The other is a B2B system that is also anticipated to be using the same technology, this system is currently in the design concept stage and so would be a green-field development. We are looking to employ a team of developers, ideally with a proven track record of previous similar projects. If you are interested and have this experience please contact me directly at *ian dot docherty at horivert dot co dot uk* with a brief resume of your experience and your hourly rate. I look forward to talking to you Regards Ian Docherty ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Deployment of many Catalyst sites on the same machine
Matt S Trout wrote: Or you could stuff 'em all in one fcgi handler with something like - package DummyApp; use Catalyst; __PACKAGE__->setup; my %rev_apps = ( MyApp => 'myapp.example.com', MyOtherApp => 'other.example.com, ); my %apps = reverse %rev_apps; foreach my $app (values %apps) { eval "require ${app}" || die $@; $app->engine(__PACKAGE__->engine); } sub handle_request { my ($self, %rest) = @_; my $host = $rest{env}{HTTP_HOST}; $apps{$host}->handle_request(%rest); } What would you suggest for multiple instances of the same application? MyApp => 'first.example.com' MyApp => 'second.example.com' I presume there would be no choice in this case but to use an fcgi handler for each one and mod-perl can't be used at all in this case? Regards Ian Docherty ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
[Catalyst] Using Workflow with Catalyst (was Making Controllers thin and Models thick)
Thanks for pointing out the workflow CPAN module. I am very interested in this for my current project and must spend some time looking at it. Has anyone actually used workflow within a Catalyst application and can they give the list their opinion and experiences with it? Regards Ian Docherty John Napiorkowski wrote: Considering that you can set actions and action classes via the central configuration file for a controller you could eventually get down to not needing any code, just configuration declarations. Still need to write a stub for your controllers though. I'm going to trying using the Workflow module (http://search.cpan.org/~jonasbn/Workflow-0.28/) on my next project and see if that can fill a missing piece for me conceptually. I think it can help cover the state issues you mentioned. Plus it has a validation framework as part of it. I end up with more in the database because the applications I'm writing will end up being used by other systems and I can't count on the PHP people validating their incoming stuff properly :) --John ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Using Workflow with Catalyst (was Making Controllers thin and Models thick)
Matt Thank you for that succinct analysis. :) I will give Class::Workflow a good look in that case. Do you know how far off Persistence using DBIC is with this? I think it would be essential for the Catalyst application I have in mind. Since this seems to be straying from discussion of Catalyst, is there somewhere else where further discussion of Class::Workflow can be taken? Regards Ian Matt S Trout wrote: On Tue, Jul 24, 2007 at 02:43:12PM +0100, Ian Docherty wrote: Thanks for pointing out the workflow CPAN module. I am very interested in this for my current project and must spend some time looking at it. Has anyone actually used workflow within a Catalyst application and can they give the list their opinion and experiences with it? It's an awful horrible piece of shit. Class::Workflow was written by our very own Yuvla Kogman to replace it and works very nicely with Catalyst. ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Using Workflow with Catalyst (was Making Controllers thin and Models thick)
John Napiorkowski wrote: - ... It's an awful horrible piece of shit. Class::Workflow was written by our very own Yuvla Kogman to replace it and works very nicely with Catalyst. Matt, I'd appreciate when you have a little time if you could share some more detailed thoughts on this, since I was literally just about to start typing code related to workflow and your message stopped me in my tracks. I originally thought to experiment with Workflow over Class::Workflow because it seemed to have a little more active development and examples as well as more development in the persistence area. Since I am a newbie to the area I am likely to need to play with it quite a bit before I am able to usefully contribute so I am looking for the most feature complete and supported system. However I am very interested in learning a system and hopefully contributing usefully to it, particularly as it can relate to Catalyst development. Thanks! --John John I think we are both at about the same position. If you wish to share experiences and discuss Class::Workflow (or Workflow) then please drop me a private email and we can perhaps work through this together. Regards Ian ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
[Catalyst] t directory hierarchy
Hi I have been using Catalyst for some time with a 'flat' test directory, with all test scripts in the same directory. The main reason for this is that when I do $ make test It does not recurse into the sub-directories and only runs test scripts in the 't' directory. However I have just found out that when I do $ prove --lib lib t/* It *does* recurse, so this would be a work-around. Is 'make test' supposed to work in that way? Regards Ian ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] t directory hierarchy
Jason Kohles wrote: On Aug 15, 2007, at 11:43 AM, Matt S Trout wrote: On Wed, Aug 15, 2007 at 11:27:14AM +0100, Ian Docherty wrote: Hi I have been using Catalyst for some time with a 'flat' test directory, with all test scripts in the same directory. The main reason for this is that when I do $ make test It does not recurse into the sub-directories and only runs test scripts in the 't' directory. That's the default behaviour. To add subdirs, put tests('t/*.t t/*/*.t'); in your Makefile.PL Or, if you have a recent version of Module::Install, just use: tests_recursive; --Jason Kohles [EMAIL PROTECTED] http://www.jasonkohles.com/ "A witty saying proves nothing." -- Voltaire ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
[Catalyst] Some guidance needed please
Hi My existing Catalyst application is being extended. I want to keep a record of previous passwords used by a user to prevent them being re-used. I have Model 'UsedPassword' to keep track of the previous 8 (say) passwords as so- package MyApp::Schema::UsedPassword; use strict; use base qw(DBIx::Class); __PACKAGE__->load_components(qw(PK::Auto Core)); __PACKAGE__->table('used_password'); __PACKAGE__->add_columns(qw(id user password)); __PACKAGE__->set_primary_key('id'); So, if I want a method (create_limited) to create a new UsedPassword object, that ensures no more that 8 (say) passwords are stored in the database (against each User) where should it go? Ideally (I think) I would like to do something like $c->model('DBIC::UsedPassword')->create_limited({ user=> $user->id, password => $password, }); but i can't see how to add it to MyApp::Schema::UsedPassword (since $c->model('DBIC::UsedPassword') returns a ResultSet not a MyApp::Schema::UsedPassword) Any other suggestions where to put it (polite one's only please)? Regards Ian ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Some guidance needed please
I have found a thread on DBIx-class mailing list that throws some light on this using http://search.cpan.org/~ash/DBIx-Class-0.08006/lib/DBIx/Class/Schema.pm#load_namespaces This seems to solve the problem for putting such logic into the Model/Schema but would it be better to put this type of logic into a business logic layer? In which case how would I obtain a $schema object? Would I have to then pass this as a parameter to the method? Regards Ian Ian Docherty wrote: Hi My existing Catalyst application is being extended. I want to keep a record of previous passwords used by a user to prevent them being re-used. I have Model 'UsedPassword' to keep track of the previous 8 (say) passwords as so- package MyApp::Schema::UsedPassword; use strict; use base qw(DBIx::Class); __PACKAGE__->load_components(qw(PK::Auto Core)); __PACKAGE__->table('used_password'); __PACKAGE__->add_columns(qw(id user password)); __PACKAGE__->set_primary_key('id'); So, if I want a method (create_limited) to create a new UsedPassword object, that ensures no more that 8 (say) passwords are stored in the database (against each User) where should it go? Ideally (I think) I would like to do something like $c->model('DBIC::UsedPassword')->create_limited({ user=> $user->id, password => $password, }); but i can't see how to add it to MyApp::Schema::UsedPassword (since $c->model('DBIC::UsedPassword') returns a ResultSet not a MyApp::Schema::UsedPassword) Any other suggestions where to put it (polite one's only please)? Regards Ian ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/ ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Some guidance needed please
Will Hawes wrote: ... Isn't this just a case of adding a create_limited() method to your model class? package MyApp::Schema::UsedPassword; ... sub create_limited { my( $self, $user, $password ) = @_; # password checking logic here } In your controller: $c->model('DBIC::UsedPassword')->create_limited( ... ); Well, that was my first thought, but I get the following error if I try to do that... Can't locate object method "create_limited" via package "DBIx::Class::ResultSet Regards Ian ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Some guidance needed please
My application has (effectively, subject to some cut and paste) the following. package MyApp::Schema; use strict; use warning; use base qw(DBIx::Class::Schema); __PACKAGE__->load_classes(qw( UsedPassword )); 1; package MyApp::Schema::UsedPassword; use strict; use warning; use base qw(DBIx::Class); __PACKAGE__->load_components(qw(PK::Auto Core)); __PACKAGE__->table('used_password'); __PACKAGE__->add_columns(qw(id user password)); __PACKAGE__->set_primary_key('id'); sub create_limited { my ($self, $user, $password) = @_; # password checking logic here } 1; package MyApp::Model::DBIC; use strict; use warning; use base qw(Catalyst::Model::DBIC::Schema); __PACKAGE__->config( schema_class=> 'MyApp::Schema', connect_info => [ MyApp->config->{db}, MyApp->config->{db_user}, MyApp->config->{db_password}, {AutoCommit => 1, quote_char => '`', name_sep => '.'}, ]); 1; As I mentioned, if I try to do a call to $c->model('DBIC::UsedPassword')->create_limited( ... ); I get the fatal error Can't locate object method "create_limited" via package "DBIx::Class::ResultSet Which is why I think this is not the approach, unless you know otherwise? Regards Ian ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Some guidance needed please
Simon Wilcox wrote: Will Hawes wrote: Whoops, my bad. $c->model() does indeed return a DBIx::Class::ResultSet, so you would need to retrieve/create an instance of your UsedPassword class from the resultset in order to call any methods on it: my $used_password = $c->model('DBIC::UsedPassword')->create( { user => 'user', password => 'password' } ); $used_password->foo_method() IIRC, can't you get the original record source back from the resultset ? my $used_password = $c->model('DBIC::UsedPassword')->result_source->create_limited(); S. Almost, if I do my $used_password = $c->model('DBIC::UsedPassword')->result_class->create_limited(); it works. So that should do for now, thanks Simon and Will for your help ;) Regards Ian ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] flash - Duplicate entries
Tobias Kremer wrote: After deploying our new Catalyst application I'm receiving this error quite often per day: "DBIx::Class::ResultSet::find_or_create(): DBI Exception: DBD::mysql::st execute failed: Duplicate entry 'flash:9b11b5354715b56c9395abdf21544e83db5b0814' for key 1 [...] at /usr/local/lib/perl5/site_perl/5.8.8/Catalyst/Plugin/ Session/Store/DBIC/Delegate.pm line 52" I'm using MySQL and I'm quite sure that this is _NOT_ a locking issue (or MySQL's fault as somebody on the list recently suggested) because the session stuff without the flash works perfectly. Any ideas what could be wrong here? Thanks! --Tobias Did I not see something on here, or on DBIx-class list some time ago to the effect that in find_or_create there is a short window where having found that a record does not exist it then creates it. I presume that two threads could each detect that a record does not exist and then one of them would create this error. Reversing the order (try a create first, catch the error, then do a find if the create fails) was ISTR the proposed answer. But this may not help you if the problem is in the Session/Store/DBIC/Delegate plugin. Regards Ian ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
[Catalyst] The model -is- where your business logic lives.
In a previous thread, Matt S Trout said. The model -is- where your business logic lives. The real question is whether your ORM should be directly in the model or not, but that's a whole different thread. Based on this I have the following simple code. package MyApp::Model::DBIC; use strict; use base qw(Catalyst::Model::DBIC::Schema); package MyApp::Schema::Demo; use base qw(DBIx::Class); __PACKAGE__->load_components(qw(PK::Auto Core)); __PACKAGE__->table('demo'); __PACKAGE__->add_columns(qw(id name state)); __PACKAGE__->set_primary_key('id'); package MyApp::Model::DBIC::Demo; sub do_some_business_logic_stuff { my ($self) = @_; if () { $self->state('pending'); $self->update; } } somewhere in my application $demo = $c->model('DBIC::Demo')->find($index); $demo->do_some_business_logic_stuff; - Is this a standard/typical/best-practice way to do this sort of thing? It seems to me that if I want to use the business logic in an external application (cronjob) then I am having to use the MyApp::Model::DBIC::Demo namespace as decreed by Catalyst (not that this is a big issue). Regards Ian ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] The model -is- where your business logic lives.
Pedro Melo wrote: [...] That's what I do with two minor adjustements: * I started using load_namespaces to control each source resultset class also; * I don't put my model inside the catalyst application. It seems to me that if I want to use the business logic in an external application (cronjob) then I am having to use the MyApp::Model::DBIC::Demo namespace as decreed by Catalyst (not that this is a big issue). se 2) above. Most of the time I have Demo::Controller, Demo::Model, Demo::View, and my schema is Demo::Schema. So I can use Demo::Schema in all my crons. (I assume you mean MyApp::Controller, MyApp::Model etc?) So, if I read the documentation correctly, I would then have my resultsets in MyApp::Schema::ResultSet::Demo and my results in MyApp::Schema::Result::Demo? I don't see how this helps me with the namespace in Catalyst, if I use $c->model('DBIC::Demo') won't it still come back with the namespace MyApp::Model::DBIC::Demo? Can you show an example of your call to load_namespaces? See the SYNOPSIS of http://search.cpan.org/perldoc?Catalyst::Model::DBIC::Schema on how to do it. Best regards, Regards Ian ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] The model -is- where your business logic lives.
Pedro Melo wrote: That's what I do with two minor adjustements: * I started using load_namespaces to control each source resultset class also; * I don't put my model inside the catalyst application. And is load_namespaces significantly slower than using load_classes with all classes explicitly specified? Regards Ian ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] The model -is- where your business logic lives.
Ian Docherty wrote: I don't see how this helps me with the namespace in Catalyst, if I use $c->model('DBIC::Demo') won't it still come back with the namespace MyApp::Model::DBIC::Demo? my bad: Stupid of me to think it matters. That's what inheritance is all about! ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] The model -is- where your business logic lives.
Matt S Trout wrote: Put this code in MyApp::Schema::Demo. I often call it e.g. MyApp::DataStore or MyApp::Domain to remind me that it's the business layer and the DBIC-ness is merely incidental. sub do_some_business_logic_stuff { my ($self) = @_; if () { $self->state('pending'); $self->update; } } somewhere in my application $demo = $c->model('DBIC::Demo')->find($index); $demo->do_some_business_logic_stuff; - Is this a standard/typical/best-practice way to do this sort of thing? It seems to me that if I want to use the business logic in an external application (cronjob) then I am having to use the MyApp::Model::DBIC::Demo namespace as decreed by Catalyst (not that this is a big issue). Having moved the logic out of MyApp::Model:: this ceases to be an issue. Don't confuse class -names- with the nature of classes. MyApp::Model:: is *adapters* that make a model available to MyApp, not where your domain model logic itself should live. I usually these days have MyApp::Web for the catalyst app instead of MyApp so I can deploy things like MyApp::DataStore from a separate dir tree. Yes I did briefly have that confusion, but I think I am mostly straight with it now and I (largely) have the layout you suggest. Just to confirm I currently have the following MyCompany::MyApp::Controller MyCompany::MyApp::View MyCompany::MyApp::Model MyCompany::MyApp::Schema (where my ORM goes) MyCompany::MyApp::Logic (where my other business logic goes) I originally created the 'Logic' namespace because I was using load_classes and by default my Schema directory had all my ORM result_source files. However I am just in the process of changing to using load_namespaces so I now have MyCompany::MyApp::Schema::Result (where I have moved all my result_sources to) MyCompany::MyApp::Schema::ResultSet leaving MyCompany::MyApp::Schema empty of classes. So I presume I can consider the MyCompany::MyApp::Schema namespace to be for my business logic that does not directly map onto a ORM? (I can't think of a good example off-hand.) One final point that I am not sure I have right. In my business logic I have certain constraints (for example the maximum length of a web-form field, e.g. username) and most of the time this constraint is defined by the database (the field length of the user.username). Now the template needs access to these values to display the appropriate error message so typically I do the following in my controller. $c->stash->{constraints}{user} = MyCompany::MyApp::Schema::Result::User->constraints; with the following in my User ORM my $constraints = { usernamename => { min_length => 0, max_length => 15, }, # etc. }; sub constraints { my ($self) = @_; return $constraints; } Which leaves me feeling a little ill-at-ease since it seems wrong to me to have a class method to do this but I don't understand why! Regards Ian ___ List: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/