Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Catalyst: Users

More natural access to model?

 

 

Catalyst users RSS feed   Index | Next | Previous | View Threaded


ptecza at uw

May 12, 2009, 2:45 AM

Post #1 of 14 (1658 views)
Permalink
More natural access to model?

Dear Catalyst users,

It's my first post here, so I would like to say "Hello" to all of us! :)

I'm writing my first Catalyst application for student registration and I
have the following tables for details about studies at our university:

CREATE TABLE studies (
id integer NOT NULL,
unit_id integer,
status integer,
limit_soft integer,
limit_hard integer
);

'id' column is a database study identifier. It's also primary key for
that table. 'unit_id' is an unit identifier of study, 'status' column
says whether registration is open/suspended/closed, 'limit_soft' and
'limit_hard' are for student number limits.

CREATE TABLE study_data (
study_id integer NOT NULL,
lang lang NOT NULL,
name text NOT NULL,
value text
);

'study_id' column is database study identifier (please look at
studies.id column), 'lang' column points language for (name, value)
pair, for example 'pl', 'en', etc. 'name' column is for name of data,
for example 'name', 'description', 'program', 'email', etc.
('study_id', 'lang', 'name') is a primary key for that table. Finally
'value' column is for data content.

I think it's very simple structure and fully understandable for you,
so it doesn't need more comments. Of course, I can also define
table 'study_data' with many columns, for example 'name', 'description',
'program', 'email', etc. but I think that its simpler structure is
better idea here, because it's more flexible. I can add new type of
data, without changing table definition.

Unfortunately, when I want to get the study details, then I need to use
the code like below:

my $study_name = '';
my $study_description = '';
my $study_program = '';
my $study_email = '';

my @studies = $c->model('DB::Studies')->all;
foreach my $study in (@studies) {
my $name = $study.study_datas.name;
my $value = $study.study_datas.value;

$study_name = $value if ($name eq 'name');
$study_description = $value if ($name eq 'description');
$study_program = $value if ($name eq 'program');
$study_email = $value if ($name eq 'email');
}

I hope you agree with me that it's not handy way...

So my question is: how can I modify my model to get the study details
in the following, more "natural" way? Is it possibble at all?

my @studies = $c->model('DB::Studies')->all;
foreach my $study in (@studies) {
$study_name = $study.study_datas.name || '';
$study_description = $study.study_datas.description || '';
$study_program = $study.study_datas.program || '';
$study_email = $study.study_datas.email || '';
}

My best regards,

Pawel



_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


zzbbyy at gmail

May 12, 2009, 3:10 AM

Post #2 of 14 (1588 views)
Permalink
Re: More natural access to model? [In reply to]

2009/5/12 Paweł Tęcza <ptecza [at] uw>:
> Dear Catalyst users,
>
> It's my first post here, so I would like to say "Hello" to all of us! :)
>
> I'm writing my first Catalyst application for student registration and I
> have the following tables for details about studies at our university:
>
> CREATE TABLE studies (
>    id integer NOT NULL,
>    unit_id integer,
>    status integer,
>    limit_soft integer,
>    limit_hard integer
> );
>
> 'id' column is a database study identifier. It's also primary key for
> that table. 'unit_id' is an unit identifier of study, 'status' column
> says whether registration is open/suspended/closed, 'limit_soft' and
> 'limit_hard' are for student number limits.
>
> CREATE TABLE study_data (
>    study_id integer NOT NULL,
>    lang lang NOT NULL,
>    name text NOT NULL,
>    value text
> );
>
> 'study_id' column is database study identifier (please look at
> studies.id column), 'lang' column points language for (name, value)
> pair, for example 'pl', 'en', etc. 'name' column is for name of data,
> for example 'name', 'description', 'program', 'email', etc.
> ('study_id', 'lang', 'name') is a primary key for that table. Finally
> 'value' column is for data content.
>
> I think it's very simple structure and fully understandable for you,
> so it doesn't need more comments. Of course, I can also define
> table 'study_data' with many columns, for example 'name', 'description',
> 'program', 'email', etc. but I think that its simpler structure is
> better idea here, because it's more flexible. I can add new type of
> data, without changing table definition.
>
> Unfortunately, when I want to get the study details, then I need to use
> the code like below:
>
> my $study_name        = '';
> my $study_description = '';
> my $study_program     = '';
> my $study_email       = '';
>
> my @studies = $c->model('DB::Studies')->all;
> foreach my $study in (@studies) {
>    my $name  = $study.study_datas.name;
>    my $value = $study.study_datas.value;
>
>    $study_name        = $value if ($name eq 'name');
>    $study_description = $value if ($name eq 'description');
>    $study_program     = $value if ($name eq 'program');
>    $study_email       = $value if ($name eq 'email');
> }
>
> I hope you agree with me that it's not handy way...
>
> So my question is: how can I modify my model to get the study details
> in the following, more "natural" way?  Is it possibble at all?
>
> my @studies = $c->model('DB::Studies')->all;
> foreach my $study in (@studies) {
>    $study_name        = $study.study_datas.name        || '';
>    $study_description = $study.study_datas.description || '';
>    $study_program     = $study.study_datas.program     || '';
>    $study_email       = $study.study_datas.email       || '';
> }
>

Hmm - there is something missing there - according to your description
above $study.study_datas.program can not identify one value - but
rather an array of values (one for each language) isn't that true?

You might also want to change the '.' to '->'.

--
Zbigniew Lukasiak
http://brudnopis.blogspot.com/
http://perlalchemy.blogspot.com/

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


ptecza at uw

May 12, 2009, 3:57 AM

Post #3 of 14 (1592 views)
Permalink
Re: More natural access to model? [In reply to]

Zbigniew Lukasiak pisze:
> 2009/5/12 Paweł Tęcza <ptecza [at] uw>:

>> So my question is: how can I modify my model to get the study details
>> in the following, more "natural" way? Is it possibble at all?
>>
>> my @studies = $c->model('DB::Studies')->all;
>> foreach my $study in (@studies) {
>> $study_name = $study.study_datas.name || '';
>> $study_description = $study.study_datas.description || '';
>> $study_program = $study.study_datas.program || '';
>> $study_email = $study.study_datas.email || '';
>> }
>>
>
> Hmm - there is something missing there - according to your description
> above $study.study_datas.program can not identify one value - but
> rather an array of values (one for each language) isn't that true?
>
> You might also want to change the '.' to '->'.

Hi Zbyszek,

Thanks for your reply! Of course, you're absolutely right. I have to
choose one language when I get all study details via my model. Sorry for
confusing, but I rather wanted to show my problem than working snippet ;)

Do you know solution of that issue? Maybe I should define subroutines in
MyApp::Schema::ResultSet::Studies module for all type of data?

Have a nice day,

P.

PS. I still remember your and Dexter presentation titled "Modern Perl"
at the Faculty of Mathematics Informatics and Mechanics at the
University of Warsaw in February :D

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


diment at gmail

May 12, 2009, 4:14 AM

Post #4 of 14 (1579 views)
Permalink
Re: More natural access to model? [In reply to]

On 12/05/2009, at 8:57 PM, Paweł Tęcza wrote:

>
> Do you know solution of that issue? Maybe I should define
> subroutines in
> MyApp::Schema::ResultSet::Studies module for all type of data?
>

Yes you should. That means that even though your code might be
horrible, you can hide the implementation details from the web
application portion of the code, and if you think about design
properly up front, removing the horrible code later on should be
pretty straightforward.




_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


ptecza at uw

May 12, 2009, 4:33 AM

Post #5 of 14 (1586 views)
Permalink
Re: More natural access to model? [In reply to]

Kieren Diment pisze:
> On 12/05/2009, at 8:57 PM, Paweł Tęcza wrote:
>
>>
>> Do you know solution of that issue? Maybe I should define
>> subroutines in
>> MyApp::Schema::ResultSet::Studies module for all type of data?
>>
>
> Yes you should. That means that even though your code might be
> horrible, you can hide the implementation details from the web
> application portion of the code, and if you think about design
> properly up front, removing the horrible code later on should be
> pretty straightforward.

Hello Kieren,

Thank you very much for your response! Is it a way to autogenerate all
necessary subroutines in a loop or I need define all of them manually?
They should have very similar body :)

Cheers,

Pawel


_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


bobtfish at bobtfish

May 12, 2009, 5:00 AM

Post #6 of 14 (1588 views)
Permalink
Re: More natural access to model? [In reply to]

Paweł Tęcza wrote:
> Thank you very much for your response! Is it a way to autogenerate all
> necessary subroutines in a loop or I need define all of them manually?
> They should have very similar body :)

Here is the gross method:

no strict 'refs';
foreach my $name (qw/ method_one method_two /) {
*{$name} = sub {
my $self = shift;
# Your code here
};
}


I'd instead recommend using Moose to do it for you:

use Moose;
foreach my $name (qw/ method_one method_two /) {
__PACKAGE__->meta->add_method($name, sub {
my $self = shift;
# Your code here
};
}

This is (a) less icky, and (b) means that your generated code will come
out nicely in stack traces / error reports, rather than being 'ANON'.

Cheers
t0m

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


ptecza at uw

May 12, 2009, 6:15 AM

Post #7 of 14 (1584 views)
Permalink
Re: More natural access to model? [In reply to]

Tomas Doran pisze:
> Paweł Tęcza wrote:
>> Thank you very much for your response! Is it a way to autogenerate all
>> necessary subroutines in a loop or I need define all of them manually?
>> They should have very similar body :)
>
> Here is the gross method:
>
> no strict 'refs';
> foreach my $name (qw/ method_one method_two /) {
> *{$name} = sub {
> my $self = shift;
> # Your code here
> };
> }
>
>
> I'd instead recommend using Moose to do it for you:
>
> use Moose;
> foreach my $name (qw/ method_one method_two /) {
> __PACKAGE__->meta->add_method($name, sub {
> my $self = shift;
> # Your code here
> };
> }
>
> This is (a) less icky, and (b) means that your generated code will come
> out nicely in stack traces / error reports, rather than being 'ANON'.

Hi Tom,

Perl is great! Thanks a lot for these methods! It's very helpful for me.
I'm your debtor now ;)

My best regards,

P.


_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


dbix-class at trout

May 12, 2009, 11:30 AM

Post #8 of 14 (1562 views)
Permalink
Re: More natural access to model? [In reply to]

On Tue, May 12, 2009 at 11:45:01AM +0200, Paweł Tęcza wrote:
> Dear Catalyst users,
>
> It's my first post here, so I would like to say "Hello" to all of us! :)
>
> I'm writing my first Catalyst application for student registration and I
> have the following tables for details about studies at our university:
>
> CREATE TABLE studies (
> id integer NOT NULL,
> unit_id integer,
> status integer,
> limit_soft integer,
> limit_hard integer
> );
>
> 'id' column is a database study identifier. It's also primary key for
> that table. 'unit_id' is an unit identifier of study, 'status' column
> says whether registration is open/suspended/closed, 'limit_soft' and
> 'limit_hard' are for student number limits.
>
> CREATE TABLE study_data (
> study_id integer NOT NULL,
> lang lang NOT NULL,
> name text NOT NULL,
> value text
> );
>
> 'study_id' column is database study identifier (please look at
> studies.id column), 'lang' column points language for (name, value)
> pair, for example 'pl', 'en', etc. 'name' column is for name of data,
> for example 'name', 'description', 'program', 'email', etc.
> ('study_id', 'lang', 'name') is a primary key for that table. Finally
> 'value' column is for data content.
>
> I think it's very simple structure and fully understandable for you,
> so it doesn't need more comments. Of course, I can also define
> table 'study_data' with many columns, for example 'name', 'description',
> 'program', 'email', etc. but I think that its simpler structure is
> better idea here, because it's more flexible. I can add new type of
> data, without changing table definition.

Well, that's a horrible idea.

The whole point of having a database is to -model- your data.

If you try and turn it into a giant hash, then of course you're going to
end up with nasty code.

I -could- explain how to clean that loop up a lot, but the reality is that
you should have actual columns for things and update your database as
required as new types of data need to be included - you'll have to update
the application anyway, so I don't see any reason not to update the database
at the same time ...

--
Matt S Trout Catalyst and DBIx::Class consultancy with a clue
Technical Director and a commit bit: http://shadowcat.co.uk/catalyst/
Shadowcat Systems Limited
mst (@) shadowcat.co.uk http://shadowcat.co.uk/blog/matt-s-trout/

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


ptecza at uw

May 12, 2009, 3:49 PM

Post #9 of 14 (1564 views)
Permalink
Re: More natural access to model? [In reply to]

Dnia 2009-05-12, wto o godzinie 19:30 +0100, Matt S Trout pisze:

> Well, that's a horrible idea.
>
> The whole point of having a database is to -model- your data.
>
> If you try and turn it into a giant hash, then of course you're going to
> end up with nasty code.
>
> I -could- explain how to clean that loop up a lot, but the reality is that
> you should have actual columns for things and update your database as
> required as new types of data need to be included - you'll have to update
> the application anyway, so I don't see any reason not to update the database
> at the same time ...

Hi Matt,

Intriguing post. My application and database design are still under
heavy development, so all ideas, suggestions and comments are very
welcome :D

My best regards,

P.



_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


darren at darrenduncan

May 12, 2009, 8:04 PM

Post #10 of 14 (1553 views)
Permalink
Re: More natural access to model? [In reply to]

Paweł Tęcza wrote:
> Dnia 2009-05-12, wto o godzinie 19:30 +0100, Matt S Trout pisze:
>> Well, that's a horrible idea.
>>
>> The whole point of having a database is to -model- your data.
>>
>> If you try and turn it into a giant hash, then of course you're going to
>> end up with nasty code.
>>
>> I -could- explain how to clean that loop up a lot, but the reality is that
>> you should have actual columns for things and update your database as
>> required as new types of data need to be included - you'll have to update
>> the application anyway, so I don't see any reason not to update the database
>> at the same time ...
>
> Intriguing post. My application and database design are still under
> heavy development, so all ideas, suggestions and comments are very
> welcome :D

A general rule of thumb is that you should be conceptualizing your databases
similar to how you conceptualize your applications.

Your database schema, such as what tables you have, and their columns, and their
column data types, and the relationships between tables and columns etc, these
are like program code, such as how you choose to decompose your application into
libraries and classes and class attributes and type constraints and input
constraints and so on. The actual data you put in your database tables is
analogous to what data you put in your application variables or objects.

Generally speaking it should be natural to change your actual database schema as
often as you change your application source code, where it makes sense; for
example, changing your schema is a similar sort of operation to changing what
attributes your object classes have or your constraints.

Or more accurately in practice, a database is more like (or in some cases,
exactly like) a shared library, where you have some classes you write once and
share in multiple applications, and if you change the library you have to
consider that impact on all the applications that use it. Hence people tend to
be more conservative in database design changes, but still one shouldn't be
afraid to do it, and all you really need is just proper communication and
planning between the involved parties so it goes smoothly.

Also, same as classes can have multiple APIs, eg keeping old ones for backwards
compatibility if old apps can't update, databases have things called views /
virtual tables which let them also have multiple APIs; this is one of the main
purposes of views in fact.

-- Darren Duncan

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


dbix-class at trout

May 13, 2009, 8:49 AM

Post #11 of 14 (1539 views)
Permalink
Re: More natural access to model? [In reply to]

On Tue, May 12, 2009 at 08:04:18PM -0700, Darren Duncan wrote:
> Paweł Tęcza wrote:
> >Dnia 2009-05-12, wto o godzinie 19:30 +0100, Matt S Trout pisze:
> >>Well, that's a horrible idea.
> >>
> >>The whole point of having a database is to -model- your data.
> >>
> >>If you try and turn it into a giant hash, then of course you're going to
> >>end up with nasty code.
> >>
> >>I -could- explain how to clean that loop up a lot, but the reality is that
> >>you should have actual columns for things and update your database as
> >>required as new types of data need to be included - you'll have to update
> >>the application anyway, so I don't see any reason not to update the
> >>database
> >>at the same time ...
> >
> >Intriguing post. My application and database design are still under
> >heavy development, so all ideas, suggestions and comments are very
> >welcome :D
>
> A general rule of thumb is that you should be conceptualizing your
> databases similar to how you conceptualize your applications.
>
> Your database schema, such as what tables you have, and their columns, and
> their column data types, and the relationships between tables and columns
> etc, these are like program code, such as how you choose to decompose your
> application into libraries and classes and class attributes and type
> constraints and input constraints and so on. The actual data you put in
> your database tables is analogous to what data you put in your application
> variables or objects.
>
> Generally speaking it should be natural to change your actual database
> schema as often as you change your application source code, where it makes
> sense; for example, changing your schema is a similar sort of operation to
> changing what attributes your object classes have or your constraints.
>
> Or more accurately in practice, a database is more like (or in some cases,
> exactly like) a shared library, where you have some classes you write once
> and share in multiple applications, and if you change the library you have
> to consider that impact on all the applications that use it. Hence people
> tend to be more conservative in database design changes, but still one
> shouldn't be afraid to do it, and all you really need is just proper
> communication and planning between the involved parties so it goes smoothly.
>
> Also, same as classes can have multiple APIs, eg keeping old ones for
> backwards compatibility if old apps can't update, databases have things
> called views / virtual tables which let them also have multiple APIs; this
> is one of the main purposes of views in fact.

Too bloody right. Care to shove this on the catwiki somewhere?

--
Matt S Trout Catalyst and DBIx::Class consultancy with a clue
Technical Director and a commit bit: http://shadowcat.co.uk/catalyst/
Shadowcat Systems Limited
mst (@) shadowcat.co.uk http://shadowcat.co.uk/blog/matt-s-trout/

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


ptecza at uw

May 15, 2009, 6:21 AM

Post #12 of 14 (1518 views)
Permalink
Re: More natural access to model? [In reply to]

Darren Duncan pisze:
> Paweł Tęcza wrote:

>> Intriguing post. My application and database design are still under
>> heavy development, so all ideas, suggestions and comments are very
>> welcome :D
>
> A general rule of thumb is that you should be conceptualizing your databases
> similar to how you conceptualize your applications.
>
> Your database schema, such as what tables you have, and their columns, and their
> column data types, and the relationships between tables and columns etc, these
> are like program code, such as how you choose to decompose your application into
> libraries and classes and class attributes and type constraints and input
> constraints and so on. The actual data you put in your database tables is
> analogous to what data you put in your application variables or objects.
>
> Generally speaking it should be natural to change your actual database schema as
> often as you change your application source code, where it makes sense; for
> example, changing your schema is a similar sort of operation to changing what
> attributes your object classes have or your constraints.
>
> Or more accurately in practice, a database is more like (or in some cases,
> exactly like) a shared library, where you have some classes you write once and
> share in multiple applications, and if you change the library you have to
> consider that impact on all the applications that use it. Hence people tend to
> be more conservative in database design changes, but still one shouldn't be
> afraid to do it, and all you really need is just proper communication and
> planning between the involved parties so it goes smoothly.
>
> Also, same as classes can have multiple APIs, eg keeping old ones for backwards
> compatibility if old apps can't update, databases have things called views /
> virtual tables which let them also have multiple APIs; this is one of the main
> purposes of views in fact.

Hello Darren,

At first, thank you very much for your advices! There are really very
valuable for me.

Yes, I'm trying to think about my data as about the objects with
attributes and create simple and flexible database without data
redundancy. For example, I have tables for users and their roles,
studies, units, registrations. I also have tables for multilanguage
attributes of studies and units. Finally, I have tables for
relationships beetwen users and their roles, units and their attributes,
studies and their attributes, etc.

I'm very curious what database schema is the best for me in your
opinion. Of course, I don't ask you for desing of the whole database.
But could you please show me what tables I should create to store
information about studies? :)

Please remember that a study has a lot multilingual attributes (name,
description, duration, fee, etc) and non-multilingual attributes
(student limits, dean's office, its address, phone number, fax and web
site, study manager, his name, e-mail, and phone number, etc).

Have a nice weekend,

P.


_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


darren at darrenduncan

May 19, 2009, 2:34 PM

Post #13 of 14 (1386 views)
Permalink
Re: More natural access to model? [In reply to]

Paweł Tęcza wrote:
> Yes, I'm trying to think about my data as about the objects with
> attributes and create simple and flexible database without data
> redundancy. For example, I have tables for users and their roles,
> studies, units, registrations. I also have tables for multilanguage
> attributes of studies and units. Finally, I have tables for
> relationships beetwen users and their roles, units and their attributes,
> studies and their attributes, etc.
>
> I'm very curious what database schema is the best for me in your
> opinion. Of course, I don't ask you for desing of the whole database.
> But could you please show me what tables I should create to store
> information about studies? :)
>
> Please remember that a study has a lot multilingual attributes (name,
> description, duration, fee, etc) and non-multilingual attributes
> (student limits, dean's office, its address, phone number, fax and web
> site, study manager, his name, e-mail, and phone number, etc).

Though I haven't actually gotten around to implementing a multilingual app yet,
I have thought these issues since long ago, so I'll summarize some principles here.

In the general case where the solution details are specific to each problem, the
answer is to simply take the proper design of a unilingual schema, where each
piece of information has its own table column, and add a new language-specifier
column, and include this column in the table's key(s) so what used to be a
single record is now allowed to be a multiplicity varying on the language.

And normalize appropriately to avoid redundant data. Either by splitting each
table with multilingual elements into 2 tables, with multilingual separated from
unilingual (the multi gets the lang-spec column). Or by turning each
multilingual element or inter-dependent set of such into a collection-typed
attribute of the single table. Some SQL DBMSs support the latter, and all
support the former; I'll demonstrate both.

For example, with 2 tables:

CREATE TABLE studies (
study_id StudyID PRIMARY KEY,
unit_id UnitID,
status Status,
limit_soft Integer,
limit_hard Integer,
deans_office Text,
address Text,
phone Text,
fax Text,
web_addr Text,
...
)

CREATE TABLE studies_multilang_attrs (
study_id StudyID FOREIGN KEY REFERENCES studies (study_id),
lang Lang NOT NULL,
name Text,
description Text,
duration Text,
fee Text,
...,
PRIMARY KEY (study_id, lang)
)

For example, with 1 table:

CREATE TABLE studies (
study_id StudyID PRIMARY KEY,
unit_id UnitID,
status Status,
limit_soft Integer,
limit_hard Integer,
deans_office Text,
address Text,
phone Text,
fax Text,
web_addr Text,
...,
multilang_attrs TABLE (
lang Lang PRIMARY KEY,
name Text NOT NULL,
description Text,
duration Text,
fee Text,
...,
)
)

Hopefully those should be self-explanatory.

Now in a common special case of multi-lingual apps, where your user interface is
data defined so for example the text strings you display to users such as
greetings or prompt messages or form field names etc are stored in data, you
could either take the same approach as above, or alternately you could invert
the design and just have a single large strings table and then all other tables
have foreign keys into it using message ids that each is in common for all
language variants of the message.

For example:

CREATE TABLE app_user_texts (
text_id Text NOT NULL,
lang Lang NOT NULL,
text Text NOT NULL,
PRIMARY KEY (text_id, lang)
)

CREATE TABLE app_form_fields (
field_name Text PRIMARY KEY,
field_label Text FOREIGN KEY REFERENCES app_user_texts (text_id),
input_constr_pattern Text,
constr_fail_msg Text FOREIGN KEY REFERENCES app_user_texts (text_id),
...
)

Or alternately:

CREATE TABLE app_form_fields (
field_name Text PRIMARY KEY,
field_label TABLE (
lang Lang PRIMARY KEY,
text Text NOT NULL
),
input_constr_pattern Text,
constr_fail_msg TABLE (
lang Lang PRIMARY KEY,
text Text NOT NULL
),
...
)

Also self-explanatory I hope. Regarding this design method, see also how Mac OS
X works, how it does multi-lingual strings support in apps, but that I think it
uses XML files instead of a SQL db but the principle is the same. Similarly,
this latter sort of design could just use app resource files in general to hold
the strings, organized that way, rather than a SQL db. Where a SQL db is useful
is if your app is of the CMS variety where users are defining what app elements
exist at runtime, and usually this info is stored in a database.

I hope that answers your question. Mainly the first/general answer I think is
more applicable in your case?

-- Darren Duncan

P.S. My use of data types like StudyId and Lang etc aren't mistakes or just
illustrations. Besides the fact that the original examples did similar, users
should be able to define their own data types. For example, StudyId may be just
defined as consisting of an Integer, but it is still a disjoint type and using
Integer ops on it like addition or division should be caught by the compiler as
an error as they don't make sense (what is the meaning of adding two study ids?).

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


ptecza at uw

Jun 5, 2009, 2:26 AM

Post #14 of 14 (1197 views)
Permalink
Re: More natural access to model? [In reply to]

Darren Duncan pisze:
> Paweł Tęcza wrote:
>> Yes, I'm trying to think about my data as about the objects with
>> attributes and create simple and flexible database without data
>> redundancy. For example, I have tables for users and their roles,
>> studies, units, registrations. I also have tables for multilanguage
>> attributes of studies and units. Finally, I have tables for
>> relationships beetwen users and their roles, units and their attributes,
>> studies and their attributes, etc.
>>
>> I'm very curious what database schema is the best for me in your
>> opinion. Of course, I don't ask you for desing of the whole database.
>> But could you please show me what tables I should create to store
>> information about studies? :)
>>
>> Please remember that a study has a lot multilingual attributes (name,
>> description, duration, fee, etc) and non-multilingual attributes
>> (student limits, dean's office, its address, phone number, fax and web
>> site, study manager, his name, e-mail, and phone number, etc).
>
> Though I haven't actually gotten around to implementing a multilingual app yet,
> I have thought these issues since long ago, so I'll summarize some principles here.
>
> In the general case where the solution details are specific to each problem, the
> answer is to simply take the proper design of a unilingual schema, where each
> piece of information has its own table column, and add a new language-specifier
> column, and include this column in the table's key(s) so what used to be a
> single record is now allowed to be a multiplicity varying on the language.
>
> And normalize appropriately to avoid redundant data. Either by splitting each
> table with multilingual elements into 2 tables, with multilingual separated from
> unilingual (the multi gets the lang-spec column). Or by turning each
> multilingual element or inter-dependent set of such into a collection-typed
> attribute of the single table. Some SQL DBMSs support the latter, and all
> support the former; I'll demonstrate both.
>
> For example, with 2 tables:
>
> CREATE TABLE studies (
> study_id StudyID PRIMARY KEY,
> unit_id UnitID,
> status Status,
> limit_soft Integer,
> limit_hard Integer,
> deans_office Text,
> address Text,
> phone Text,
> fax Text,
> web_addr Text,
> ...
> )
>
> CREATE TABLE studies_multilang_attrs (
> study_id StudyID FOREIGN KEY REFERENCES studies (study_id),
> lang Lang NOT NULL,
> name Text,
> description Text,
> duration Text,
> fee Text,
> ...,
> PRIMARY KEY (study_id, lang)
> )

Hello Darren,

I'm so sorry for a long silence, but I had a lot of work in the last
weeks...

Thank you veru much for your interesting message! I designed my data
base schema before in very similar way like you :)

> Now in a common special case of multi-lingual apps, where your user interface is
> data defined so for example the text strings you display to users such as
> greetings or prompt messages or form field names etc are stored in data, you
> could either take the same approach as above, or alternately you could invert
> the design and just have a single large strings table and then all other tables
> have foreign keys into it using message ids that each is in common for all
> language variants of the message.
>
> For example:
>
> CREATE TABLE app_user_texts (
> text_id Text NOT NULL,
> lang Lang NOT NULL,
> text Text NOT NULL,
> PRIMARY KEY (text_id, lang)
> )
>
> CREATE TABLE app_form_fields (
> field_name Text PRIMARY KEY,
> field_label Text FOREIGN KEY REFERENCES app_user_texts (text_id),
> input_constr_pattern Text,
> constr_fail_msg Text FOREIGN KEY REFERENCES app_user_texts (text_id),
> ...
> )

Hm. It's new and interesting idea for me. I always store user interface
data in the template files. Together with multi-lingual logic.

I guess I can also put error/warning messages into my data base. But it
has one weak point. If connection to database is broken, then user can't
see any messages...

> Also self-explanatory I hope. Regarding this design method, see also how Mac OS
> X works, how it does multi-lingual strings support in apps, but that I think it
> uses XML files instead of a SQL db but the principle is the same. Similarly,
> this latter sort of design could just use app resource files in general to hold
> the strings, organized that way, rather than a SQL db. Where a SQL db is useful
> is if your app is of the CMS variety where users are defining what app elements
> exist at runtime, and usually this info is stored in a database.

Trying Mac OS X will not be easy for me, because I don't have any
machine with it. I'm Linux and OpenSolaris user :)

Storing interface data in the files is probably more safe solution...
But I agree that putting them into data base has advantages too :)

My best regards,

Pawel

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/

Catalyst users RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.