@@ -15,15 +15,6 @@ A Simple Example: A Product
1515In this section, you'll configure your database, create a ``Product `` object,
1616persist it to the database and fetch it back out.
1717
18- .. sidebar :: Code along with the Example
19-
20- If you want to follow along with the example in this chapter, create an
21- AcmeStoreBundle via:
22-
23- .. code-block :: bash
24-
25- $ php app/console generate:bundle --namespace=Acme/StoreBundle
26-
2718Configuring the Database
2819~~~~~~~~~~~~~~~~~~~~~~~~
2920
@@ -42,12 +33,6 @@ information. By convention, this information is usually configured in an
4233 database_password : password
4334 database_charset : UTF8
4435
45- .. note ::
46-
47- Defining the configuration via ``parameters.yml `` is just a convention. The
48- parameters defined in that file are referenced by the main configuration
49- file when setting up Propel:
50-
5136 These parameters defined in ``parameters.yml `` can now be included in the
5237configuration file (``config.yml ``):
5338
@@ -60,7 +45,13 @@ configuration file (``config.yml``):
6045 password : " %database_password%"
6146 dsn : " %database_driver%:host=%database_host%;dbname=%database_name%;charset=%database_charset%"
6247
63- Now that Propel knows about your database, Symfony can create the database for
48+ .. note ::
49+
50+ Defining the configuration via ``parameters.yml `` is a
51+ :ref: `Symfony Framework Best Practice <best-practices-canonical-parameters >`,
52+ feel free to do it differently if that suits your application better.
53+
54+ Now that Propel knows about your database, it can create the database for
6455you:
6556
6657.. code-block :: bash
7061 .. note ::
7162
7263 In this example, you have one configured connection, named ``default ``. If
73- you want to configure more than one connection, read the ` PropelBundle
74- configuration section `_.
64+ you want to configure more than one connection, read the
65+ ` PropelBundle configuration section `_.
7566
7667Creating a Model Class
7768~~~~~~~~~~~~~~~~~~~~~~
@@ -86,14 +77,15 @@ generated by Propel contain some business logic.
8677
8778Suppose you're building an application where products need to be displayed.
8879First, create a ``schema.xml `` file inside the ``Resources/config `` directory
89- of your AcmeStoreBundle :
80+ of your AppBundle :
9081
9182.. code-block :: xml
9283
84+ <!-- src/AppBundle/Resources/config/schema.xml -->
9385 <?xml version =" 1.0" encoding =" UTF-8" ?>
9486 <database
9587 name =" default"
96- namespace =" Acme\StoreBundle \Model"
88+ namespace =" AppBundle \Model"
9789 defaultIdMethod =" native" >
9890
9991 <table name =" product" >
@@ -129,7 +121,7 @@ After creating your ``schema.xml``, generate your model from it by running:
129121 $ php app/console propel:model:build
130122
131123 This generates each model class to quickly develop your application in the
132- ``Model/ `` directory of the AcmeStoreBundle bundle.
124+ ``Model/ `` directory of the AppBundle bundle.
133125
134126Creating the Database Tables/Schema
135127~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -150,32 +142,39 @@ match the schema you've specified.
150142.. tip ::
151143
152144 You can run the last three commands combined by using the following
153- command: ``php app/console propel:build --insert-sql ``.
145+ command:
146+
147+ .. code-block :: bash
148+
149+ $ php app/console propel:build --insert-sql
154150
155151 Persisting Objects to the Database
156152~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
157153
158154Now that you have a ``Product `` object and corresponding ``product `` table,
159155you're ready to persist data to the database. From inside a controller, this
160- is pretty easy. Add the following method to the ``DefaultController `` of the
156+ is pretty easy. Add the following method to the ``ProductController `` of the
161157bundle::
162158
163- // src/Acme/StoreBundle/ Controller/DefaultController .php
159+ // src/AppBundle/ Controller/ProductController .php
164160
165161 // ...
166- use Acme\StoreBundle \Model\Product;
162+ use AppBundle \Model\Product;
167163 use Symfony\Component\HttpFoundation\Response;
168164
169- public function createAction()
165+ class ProductController extends Controller
170166 {
171- $product = new Product();
172- $product->setName('A Foo Bar');
173- $product->setPrice(19.99);
174- $product->setDescription('Lorem ipsum dolor');
167+ public function createAction()
168+ {
169+ $product = new Product();
170+ $product->setName('A Foo Bar');
171+ $product->setPrice(19.99);
172+ $product->setDescription('Lorem ipsum dolor');
175173
176- $product->save();
174+ $product->save();
177175
178- return new Response('Created product id '.$product->getId());
176+ return new Response('Created product id '.$product->getId());
177+ }
179178 }
180179
181180In this piece of code, you instantiate and work with the ``$product `` object.
@@ -194,21 +193,27 @@ Fetching an object back from the database is even easier. For example, suppose
194193you've configured a route to display a specific ``Product `` based on its ``id ``
195194value::
196195
196+ // src/AppBundle/Controller/ProductController.php
197+
197198 // ...
198- use Acme\StoreBundle \Model\ProductQuery;
199+ use AppBundle \Model\ProductQuery;
199200
200- public function showAction($id)
201+ class ProductController extends Controller
201202 {
202- $product = ProductQuery::create()
203- ->findPk($id);
203+ // ...
204204
205- if (!$product) {
206- throw $this->createNotFoundException(
207- 'No product found for id '.$id
208- );
209- }
205+ public function showAction($id)
206+ {
207+ $product = ProductQuery::create()->findPk($id);
208+
209+ if (!$product) {
210+ throw $this->createNotFoundException(
211+ 'No product found for id '.$id
212+ );
213+ }
210214
211- // ... do something, like pass the $product object into a template
215+ // ... do something, like pass the $product object into a template
216+ }
212217 }
213218
214219Updating an Object
@@ -217,31 +222,37 @@ Updating an Object
217222Once you've fetched an object from Propel, updating it is easy. Suppose you
218223have a route that maps a product id to an update action in a controller::
219224
225+ // src/AppBundle/Controller/ProductController.php
226+
220227 // ...
221- use Acme\StoreBundle \Model\ProductQuery;
228+ use AppBundle \Model\ProductQuery;
222229
223- public function updateAction($id)
230+ class ProductController extends Controller
224231 {
225- $product = ProductQuery::create()
226- ->findPk($id);
232+ // ...
227233
228- if (!$product) {
229- throw $this->createNotFoundException(
230- 'No product found for id '.$id
231- );
232- }
234+ public function updateAction($id)
235+ {
236+ $product = ProductQuery::create()->findPk($id);
233237
234- $product->setName('New product name!');
235- $product->save();
238+ if (!$product) {
239+ throw $this->createNotFoundException(
240+ 'No product found for id '.$id
241+ );
242+ }
236243
237- return $this->redirect($this->generateUrl('homepage'));
244+ $product->setName('New product name!');
245+ $product->save();
246+
247+ return $this->redirect($this->generateUrl('homepage'));
248+ }
238249 }
239250
240251Updating an object involves just three steps:
241252
242- #. fetching the object from Propel (line 6 - 13 );
243- #. modifying the object (line 15 );
244- #. saving it (line 16 ).
253+ #. fetching the object from Propel (line 12 - 18 );
254+ #. modifying the object (line 20 );
255+ #. saving it (line 21 ).
245256
246257Deleting an Object
247258~~~~~~~~~~~~~~~~~~
@@ -257,16 +268,22 @@ Querying for Objects
257268Propel provides generated ``Query `` classes to run both basic and complex queries
258269without any work::
259270
260- \Acme\StoreBundle\Model\ProductQuery::create()->findPk($id);
271+ use AppBundle\Model\ProductQuery;
272+ // ...
273+
274+ ProductQuery::create()->findPk($id);
261275
262- \Acme\StoreBundle\Model\ ProductQuery::create()
276+ ProductQuery::create()
263277 ->filterByName('Foo')
264278 ->findOne();
265279
266280Imagine that you want to query for products which cost more than 19.99, ordered
267281from cheapest to most expensive. From inside a controller, do the following::
268282
269- $products = \Acme\StoreBundle\Model\ProductQuery::create()
283+ use AppBundle\Model\ProductQuery;
284+ // ...
285+
286+ $products = ProductQuery::create()
270287 ->filterByPrice(array('min' => 19.99))
271288 ->orderByPrice()
272289 ->find();
@@ -279,20 +296,26 @@ abstraction layer.
279296If you want to reuse some queries, you can add your own methods to the
280297``ProductQuery `` class::
281298
282- // src/Acme/StoreBundle/Model/ProductQuery.php
299+ // src/AppBundle/Model/ProductQuery.php
300+
301+ // ...
283302 class ProductQuery extends BaseProductQuery
284303 {
285304 public function filterByExpensivePrice()
286305 {
287- return $this
288- ->filterByPrice(array('min' => 1000));
306+ return $this->filterByPrice(array(
307+ 'min' => 1000,
308+ ));
289309 }
290310 }
291311
292- But note that Propel generates a lot of methods for you and a simple
312+ However, note that Propel generates a lot of methods for you and a simple
293313``findAllOrderedByName() `` can be written without any effort::
294314
295- \Acme\StoreBundle\Model\ProductQuery::create()
315+ use AppBundle\Model\ProductQuery;
316+ // ...
317+
318+ ProductQuery::create()
296319 ->orderByName()
297320 ->find();
298321
@@ -310,7 +333,7 @@ Start by adding the ``category`` definition in your ``schema.xml``:
310333 <?xml version =" 1.0" encoding =" UTF-8" ?>
311334 <database
312335 name =" default"
313- namespace =" Acme\StoreBundle \Model"
336+ namespace =" AppBundle \Model"
314337 defaultIdMethod =" native" >
315338
316339 <table name =" product" >
@@ -382,12 +405,14 @@ Saving Related Objects
382405
383406Now, try the code in action. Imagine you're inside a controller::
384407
408+ // src/AppBundle/Controller/ProductController.php
409+
385410 // ...
386- use Acme\StoreBundle \Model\Category;
387- use Acme\StoreBundle \Model\Product;
411+ use AppBundle \Model\Category;
412+ use AppBundle \Model\Product;
388413 use Symfony\Component\HttpFoundation\Response;
389414
390- class DefaultController extends Controller
415+ class ProductController extends Controller
391416 {
392417 public function createProductAction()
393418 {
@@ -418,21 +443,25 @@ Fetching Related Objects
418443~~~~~~~~~~~~~~~~~~~~~~~~
419444
420445When you need to fetch associated objects, your workflow looks just like it did
421- before. First, fetch a ``$product `` object and then access its related
422- ``Category ``::
446+ before: Fetch a ``$product `` object and then access its related ``Category ``::
447+
448+ // src/AppBundle/Controller/ProductController.php
423449
424450 // ...
425- use Acme\StoreBundle \Model\ProductQuery;
451+ use AppBundle \Model\ProductQuery;
426452
427- public function showAction($id)
453+ class ProductController extends Controller
428454 {
429- $product = ProductQuery::create()
430- ->joinWithCategory()
431- ->findPk($id);
455+ public function showAction($id)
456+ {
457+ $product = ProductQuery::create()
458+ ->joinWithCategory()
459+ ->findPk($id);
432460
433- $categoryName = $product->getCategory()->getName();
461+ $categoryName = $product->getCategory()->getName();
434462
435- // ...
463+ // ...
464+ }
436465 }
437466
438467Note, in the above example, only one query was made.
@@ -454,14 +483,14 @@ inserted, updated, deleted, etc).
454483
455484To add a hook, just add a new method to the object class::
456485
457- // src/Acme/StoreBundle /Model/Product.php
486+ // src/AppBundle /Model/Product.php
458487
459488 // ...
460489 class Product extends BaseProduct
461490 {
462491 public function preInsert(\PropelPDO $con = null)
463492 {
464- // do something before the object is inserted
493+ // ... do something before the object is inserted
465494 }
466495 }
467496
@@ -488,8 +517,8 @@ Behaviors
488517---------
489518
490519All bundled behaviors in Propel are working with Symfony. To get more
491- information about how to use Propel behaviors, look at the ` Behaviors reference
492- section `_.
520+ information about how to use Propel behaviors, look at the
521+ ` Behaviors reference section `_.
493522
494523Commands
495524--------
0 commit comments