Hi,
I seem to be going round in circles trying to understand how I can access my adapted class (Catalyst::Model::Adaptor) from within a normal Catalyst model.
I have a database class (using DBI) called 'Sql', which I have now wrapped up in an adapted model 'Members'. - so far so good
I then have my actual model called 'Login', that needs to use this adapted model class .
In my 'Login' model it needs access to 'Members', which is set as an object attribute along with additional application context ($c) data for session and IP.
Code:
package Members::Model::Login;
use Moose;
use namespace::autoclean;
extends 'Catalyst::Model';
# Attributes
has 'Members' => (
is => 'ro',
isa => 'Object'
);
has 'IP' => (
is => 'ro',
isa => 'Str'
);
has 'Session' => (
is => 'ro',
isa => 'HashRef'
);
has 'SessionID' => (
is => 'ro',
isa => 'Str'
);
I would like to then in my controller use the 'Login' model.
I have found to make this work, my controller has to access it via...
Code:
$c->model('Login')->new(
Members => $c->model('Members'),
IP => $c->req->address,
Session => $c->session,
SessionID => $c->sessionid
)->LogCheck();
Is this the only way to give my 'Login' model access to my 'Members' model?
I would prefer Catalyst to set up the attribute 'Members' itself when instantiating the 'Login' model so I don't keep having to pass it in the constructor.
Is this also possible for the other attributes?
If so how would I do this? So I could simply then use
Code:
$c->model('Login')->LogCheck();
Though I assume I have to pass in $c->session etc. each time otherwise all requests would use the same details, but it would be good if I could get 'Members' auto loaded, as it never changes so the one instantiation of it is fine.
After all Catalyst has already instantiated 'Members', so I just want access to this object from the 'Login' model.
Though as I'm using the 'new' constructor on my 'Login' model, am I getting a newly created model object each time anyway and not the Catalyst auto instantiated one?
I'd also like to make the 'Members' attribute set to 'required => 1', but currently the app falls over because when Catalyst auto instantiates 'Login', it isn't passing in the required attribute 'Members'
I have read that you can add the Catalyst context to your model as an alternative option via
Code:
__PACKAGE__->mk_accessors(qw|context|);
sub ACCEPT_CONTEXT {
my ($self, $c, @args) = @_;
$self->context($c);
return $self;
}
So in my 'Login' model I can then use
Code:
$self->context->model('Members')->my_method
instead of having 'Members' as an attribute of the 'Login' model.
But I've also read to steer well clear of this and not to do it, as it binds your app to Catalyst and is just as bad as passing in $c
Plus it's pretty horrible syntax to have to use anyway, when my current solution is simply
Code:
$self->Members->my_method
Which is at least keeping my model unbound from Catalyst and only loosley coupled to the data types it needs to function on its own.
So help understanding all this really is appreciated.
Regards,
1DMF