Day 2 -- set a data model

Source: Internet
Author: User
Tags sqlite database

Day 2 -- set a data model

Symfony Review

On the first day of this long but interesting guide, we learned how to install the symfony framework and set up a new program and development environment, the source code version control is used to store the source code safely. By the way, the program source code generated on the first day can be obtained in the source code repository of askeet:
Http://svn.askeet.com/

The goal of the next day is to define the final result from a functional perspective, design the data model and code. This includes generating an object relationship ing and using them to create, retrieve, and update records in the program framework data.

This is indeed a lot of content. Let's get started.

Unveil the program

What do we want to know? This is an interesting question. There are many interesting answers to this question, such:

How can I bring my blog traffic?
What is the best web framework?

There is not only one answer to all these questions, but the best answer lies in our point of view. In fact, only one answer is usually the least boring, but there is only one answer on the web. This is unfair.

Come to askeet. This is a website that helps people find answers to their questions. Who will answer these questions? All. Everyone can evaluate others' answers, so the most popular answers are more visible. As the number of problems increases, the use of classes and subclasses to organize the problem becomes unfeasible. Therefore, the problem creator can use any words he wants to tag the problem. Of course, the popular tag programs are represented by a tag set. If you want to follow an answer to a question, you can subscribe to the question RSS feed. All of these features must be elegant and lightweight, so that all these interactions do not need a new Ajax page. In fact, you need a backend to organize questions and answers, or manually add a question that the Administrator deems meaningful.

Maybe you will ask: Have I ever seen such a website on the web? Of course, if you do, then we are right, but if you have seen faqts, eHow, ask leeves or similar content, there is no aggregate answer, no Ajax, no RSS, there are no tags, so these are not the same as our website. Here we will discuss the process sequence of Web2.0.

The askeet directory is not just a website. It is a program that anyone can download, secure at home or on the company's website, modify or add new features. The source code will be released in the form of an open source code license. Is your HR manager looking for a knowledge management system? What skills do you want to learn about car repair? Do you not want to develop a FAQ for your website? You don't have to look for it any more, because there is askeet. Of course, he will exist. It is our Christmas gift.

Where to start?

So how do you start a symfony program? It depends on you. If you are an XP expert, you can write a story, plan a game, and find a partner for Pair programming, or if you are a UML fan, you can compile a detailed website description with a framework for all objects, States, and interactions.

However, this tutorial is not about general program development, so we start with a basic relational data model and add work features step by step. All we need is a sequence available at the end of every day, rather than a huge program code that does not output anything. Ideally, we should write unit tests for every new feature we have added, but we don't actually have time to do this. If you want to perform a unit test, it takes one day. So let's continue reading.

For this project, we will use a MySQL database with an inonodb table type, so that we can use centralized control and transaction support. In the previous step, we will use an SQLite database to avoid designing an actual database. This requires some minor modifications in the databases. yml file. We will leave this work for you as an exploration exercise.

Data Model

LINK model

Obviously, there must be a 'question' and an 'answer' data table. We need a 'user' data table and a 'interest 'data table to store users interested in a problem, and record a user's pertinent comments on an answer in a 'relevancy 'data table.

The user needs to confirm to add a question, evaluate the answer, or delete the interest in a question. The user does not need to confirm the answer, but an answer is always linked to a user, so that the user who gives the most popular answer can distinguish. Answers released without confirmation will be displayed as a contribution of a common user, called 'anonus us coward '. It is easy to understand the entire relational data table:
ERD

Note that a created_at field is declared for each data table. Symfony recognizes such a domain and sets the current system time when the record is created. This is also similar to the updated_at field: when the record is updated, it is set to the system time.

Schema. xml

The relational model has been converted into a configuration file that symfony can understand. This is the purpose of the schema. xml or schema. yml file, which is located in the askeet/config/directory. Symfony supports XML or yaml format syntax.

There are two ways to write this file: handwriting, which we like, or generated by an existing database. Let's take a look at the first solution.

First, we need to remove the default yaml style file:

$ SVN Delete config/Schema. yml

The syntax of the schema. yml file is quite simple: it is an XML file in which the <Table> tag contains the <column>, <foreign-key>, and <index> tags. Once we write one, we can write all of them. The schema. yml file of the relational model described above is as follows:

<? XML version = "1.0" encoding = "UTF-8"?>
<Database name = "propel" defaultidmethod = "native" noxsd = "true">
<Table name = "ask_question" phpname = "Question">
<Column name = "ID" type = "integer" required = "true" primarykey = "true" autoincrement = "true"/>
<Column name = "user_id" type = "integer"/>
<Foreign-key foreigntable = "ask_user">
<Reference local = "user_id" Foreign = "ID"/>
</Foreign-key>
<Column name = "title" type = "longvarchar"/>
<Column name = "body" type = "longvarchar"/>
<Column name = "created_at" type = "timestamp"/>
<Column name = "updated_at" type = "timestamp"/>
</Table>
 
<Table name = "ask_answer" phpname = "Answer">
<Column name = "ID" type = "integer" required = "true" primarykey = "true" autoincrement = "true"/>
<Column name = "question_id" type = "integer"/>
<Foreign-key foreigntable = "ask_question">
<Reference local = "question_id" Foreign = "ID"/>
</Foreign-key>
<Column name = "user_id" type = "integer"/>
<Foreign-key foreigntable = "ask_user">
<Reference local = "user_id" Foreign = "ID"/>
</Foreign-key>
<Column name = "body" type = "longvarchar"/>
<Column name = "created_at" type = "timestamp"/>
</Table>
 
<Table name = "ask_user" phpname = "user">
<Column name = "ID" type = "integer" required = "true" primarykey = "true" autoincrement = "true"/>
<Column name = "nickname" type = "varchar" size = "50"/>
<Column name = "first_name" type = "varchar" size = "100"/>
<Column name = "last_name" type = "varchar" size = "100"/>
<Column name = "created_at" type = "timestamp"/>
</Table>
 
<Table name = "ask_interest" phpname = "interest">
<Column name = "question_id" type = "integer" primarykey = "true"/>
<Foreign-key foreigntable = "ask_question">
<Reference local = "question_id" Foreign = "ID"/>
</Foreign-key>
<Column name = "user_id" type = "integer" primarykey = "true"/>
<Foreign-key foreigntable = "ask_user">
<Reference local = "user_id" Foreign = "ID"/>
</Foreign-key>
<Column name = "created_at" type = "timestamp"/>
</Table>
 
<Table name = "ask_relevancy" phpname = "relevancy">
<Column name = "answer_id" type = "integer" primarykey = "true"/>
<Foreign-key foreigntable = "ask_answer">
<Reference local = "answer_id" Foreign = "ID"/>
</Foreign-key>
<Column name = "user_id" type = "integer" primarykey = "true"/>
<Foreign-key foreigntable = "ask_user">
<Reference local = "user_id" Foreign = "ID"/>
</Foreign-key>
<Column name = "score" type = "integer"/>
<Column name = "created_at" type = "timestamp"/>
</Table>
 
</Database>

Note: In this file, set the data name to propel regardless of the actual database name. This is a parameter used to connect the propel layer to the symfony framework. The actual database name will be defined in the databases. yml configuration file.

If we have a database, we have another method to create the schema. yml file. That is to say, if we are familiar with a graphical database design tool, we prefer to build a schema from the generated MySQL database. Before doing this, we only need to edit the propel. ini file in the askeet/config/directory and input the connection string to our database:

Propel. database. url = MYSQL: // username: password @ localhost/databasename

Here, username, password, localhost, and databasename are the actual connection settings of our database. Now we can call the propel-Build-schema command (in the askeet/directory) to generate schema. XML from the database:

$ Symfony propel-Build-schema

In addition to creating a schema. xml file, you can also create a schema. yml file using the syntax format of yaml:

[Yml] propel: _ attributes: {noxsd: false, defaultidmethod: None, package: Lib. Model}

Ask_question:
_ Attributes: {phpname: Question, idmethod: Native}
ID: {type: integer, required: True, primarykey: True, autoincrement: true}
User_id: {type: integer, foreigntable: ask_user, foreignreference: Id}
Title: {type: longvarchar}
Body: {type: longvarchar}
Created_at :~
Updated_at :~

Ask_answer:
_ Attributes: {phpname: Answer, idmethod: Native}
ID: {type: integer, required: True, primarykey: True, autoincrement: true}
Question_id: {type: integer, foreigntable: ask_question, foreignreference: Id}
User_id: {type: integer, foreigntable: ask_user, foreignreference: Id}
Body: {type: longvarchar}
Created_at :~

Ask_user:
_ Attributes: {phpname: User, idmethod: Native}
ID: {type: integer, required: True, primarykey: True, autoincrement: true}
Nickname: {type: varchar (50), required: True, index: true}
First_name: varchar (100)
Last_name: varchar (100)
Created_at :~

Ask_interest:
_ Attributes: {phpname: interest, idmethod: Native}
Question_id: {type: integer, foreigntable: ask_question, foreignreference: Id}
User_id: {type: integer, foreigntable: ask_user, foreignreference: Id}
Created_at :~

Ask_relevancy:
_ Attributes: {phpname: relevancy, idmethod: Native}
Answer_id: {type: integer, foreigntable: ask_answer, foreignreference: Id}
User_id: {type: integer, foreigntable: ask_user, foreignreference: Id}
Score: {type: integer}
Created_at :~

Build an object model

To use the inonodb engine, you must add the following line to the propel. ini file in the askeet/config/directory:

Propel. MySQL. tabletype = InnoDB

Once the schema. xml file is created, an object model can be generated based on this relational model. In symfony, the object-to-image relationship ing is handled by propel, but encapsulated in the symfony command:

$ Symfony propel-Build-Model

This command is generated (we need to call it in the root directory of the askeet project) and corresponds to the table defined in the schema, and has a standard access method (-> get () and-> set () method ). You can view the generated code in the askeet/lib/model/OM/directory. If we want to know why two classes are required for each data table, we can view the model chapter in symfony. Each time we execute build-model, these classes will be overwritten, which often happens in this project. So if we need to add a method to the model object, we must modify the classes in the askeet/lib/model/directory-they are inherited by/Om.

Database

Connection

Now the database has a database model. Now we need to connect the project to the MySQL database. First, we need to create a database in MySQL:

$ Mysqladmin-u youruser-P create askeet

Open the configuration file askeet/config/databases. yml. If this is the first time we use symfony, we will find that the symfony configuration file is written in yaml syntax. This syntax is very simple, but there is a convention: You can only use spaces instead of tabs. Once we know this, we can write a file and add the connection settings to our database under all: class:
ALL:
Propel:
Class: sfpropeldatabase
Param:
Phptype: MySQL
HOST: localhost
Database: askeet
Username: youruser
Password: yourpasswd

For more information about symfony configuration and yaml file, see the actual configuration chapter of symfony.

Build

If the schema. yml file is not manually written, and the corresponding data table exists in our database, we can skip this part.

For keyboard fans, this is an amazing place: we do not need to create data tables and corresponding data columns in the MySQL database. We have completed the work in schema. XML, so symfony will create all SQL build statements for us:

$ Symfony propel-Build-SQL

This command will create a Lib. model. schema. SQL file in the askeet/data/SQL/directory. Use MYSQL as an SQL command:

$ Mysql-u youruser-P askeet <data/SQL/lib. model. schema. SQL

Correspondingly, we can also use the propel-insert-SQL task:

$ Symfony propel-insert-SQL

Test data access through crud

Now you can test whether these tasks can work properly. So far, our browser has no function, and we still want to create a web program. So let's create a basic symfony template and action set to process the data in the 'question' data table. This allows us to create problems and display them.

In the askeet/directory, enter the following command:

$ Symfony propel-generate-Crud frontend Question

This will generate a framework for a question module in the frontend program. This framework is based on the question propel object model and has basic creation, retrieval, update, and deletion actions. Don't be confused: A framework is not a completed program, but a basic structure. On it, we can develop new features, add business rules, and customize display.

The actions created by a crud generator are listed as follows:

Name Description
List displays all records of a data table.
Index to list
Show Displays all data domains of a specified record.
Edit displays a form to create a new record or edit an existing record.
Update modifies a record by specifying parameters in the request, and then redirects to show
Delete deletes a specified record from the data table.

We can learn more about generated actions in the framework section of symfony.

Whenever we add a new class that needs to be automatically loaded, do not forget to clear the configuration cache (to reload the automatically loaded cache ):
$ Symfony CC frontend config

Now we can use the following URL for online testing:
Http: // askeet/question

Now we can perform some operations. Add questions, edit them, and delete them. If it works properly, this means that the object model is correct, that is, the connection to the database is correct, and the relational model of the database to the object model of the database is correct. This is a good function test.

Tomorrow

We didn't write a line of PHP code, but we already have an available basic program. This is not bad for the next day. Tomorrow, we will write some code to create a welcome homepage to display the problem list. We can also use a processing operation to add data to our database and learn how to expand the module.

 Original article addressHttp://www.symfony-project.com

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.