package MyApp::Schema::Result::User; __PACKAGE__->has_many( "user_roles", "MyApp::Schema::Result::UserRole", { "foreign.username" => "self.username" }, { cascade_copy => 0, cascade_delete => 0 }, ); __PACKAGE__->many_to_many("roles", "user_roles", "role"); package MyApp::Schema::Result::Role; __PACKAGE__->has_many( "role_pages", "MyApp::Schema::Result::RolePage", { "foreign.role" => "self.role" }, { cascade_copy => 0, cascade_delete => 0 }, ); __PACKAGE__->has_many( "user_roles", "MyApp::Schema::Result::UserRole", { "foreign.role" => "self.role" }, { cascade_copy => 0, cascade_delete => 0 }, ); __PACKAGE__->many_to_many("page_names", "role_pages", "page_name") __PACKAGE__->many_to_many("usernames", "user_roles", "username"); package MyApp::Schema::Result::Page; __PACKAGE__->has_many( "role_pages", "MyApp::Schema::Result::RolePage", { "foreign.page_name" => "self.page_name" }, { cascade_copy => 0, cascade_delete => 0 }, ); __PACKAGE__->many_to_many("roles", "role_pages", "role"); package MyApp::Schema::Result::UserRole; __PACKAGE__->belongs_to( "role", "MyApp::Schema::Result::Role", { role => "role" }, { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" }, ); __PACKAGE__->belongs_to( "username", "MyApp::Schema::Result::User", { username => "username" }, { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" }, ); package MyApp::Schema::Result::RolePage; __PACKAGE__->belongs_to( "page_name", "MyApp::Schema::Result::Page", { page_name => "page_name" }, { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" }, ); __PACKAGE__->belongs_to( "role", "MyApp::Schema::Result::Role", { role => "role" }, { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" }, ); #### foreach my $page ($c->user->pages) { # do something with $page } #### sub pages { my ($self) = @_; return $self->result_source->schema->resultset('RolePage')->search_rs( { 'username.username' => $self->username, }, { join => [ { role => {user_roles => 'username'}, }, 'page_name', ], } ); } #### package MyApp::Schema::ResultSet::RolePage; use Moose; use namespace::autoclean; extends qw/MyApp::Schema::ResultSetX::DisplayTable/; has '+name' => ( default => 'RolePage' ); #### sub pages { my $self = shift; return $self->search_related('user_roles') ->search_related('role') ->search_related('role_pages') ->search_related('page_name'); # Alternatively, if you need to eliminate duplicates: # ->search_related('page_name', {}, {distinct => 1}); }