@@ -15,15 +15,6 @@ A Simple Example: A Product
15
15
In this section, you'll configure your database, create a ``Product `` object,
16
16
persist it to the database and fetch it back out.
17
17
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
-
27
18
Configuring the Database
28
19
~~~~~~~~~~~~~~~~~~~~~~~~
29
20
@@ -42,12 +33,6 @@ information. By convention, this information is usually configured in an
42
33
database_password : password
43
34
database_charset : UTF8
44
35
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
-
51
36
These parameters defined in ``parameters.yml `` can now be included in the
52
37
configuration file (``config.yml ``):
53
38
@@ -60,7 +45,13 @@ configuration file (``config.yml``):
60
45
password : " %database_password%"
61
46
dsn : " %database_driver%:host=%database_host%;dbname=%database_name%;charset=%database_charset%"
62
47
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
64
55
you:
65
56
66
57
.. code-block :: bash
70
61
.. note ::
71
62
72
63
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 `_.
75
66
76
67
Creating a Model Class
77
68
~~~~~~~~~~~~~~~~~~~~~~
@@ -86,14 +77,15 @@ generated by Propel contain some business logic.
86
77
87
78
Suppose you're building an application where products need to be displayed.
88
79
First, create a ``schema.xml `` file inside the ``Resources/config `` directory
89
- of your AcmeStoreBundle :
80
+ of your AppBundle :
90
81
91
82
.. code-block :: xml
92
83
84
+ <!-- src/AppBundle/Resources/config/schema.xml -->
93
85
<?xml version =" 1.0" encoding =" UTF-8" ?>
94
86
<database
95
87
name =" default"
96
- namespace =" Acme\StoreBundle \Model"
88
+ namespace =" AppBundle \Model"
97
89
defaultIdMethod =" native" >
98
90
99
91
<table name =" product" >
@@ -129,7 +121,7 @@ After creating your ``schema.xml``, generate your model from it by running:
129
121
$ php app/console propel:model:build
130
122
131
123
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.
133
125
134
126
Creating the Database Tables/Schema
135
127
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -150,32 +142,39 @@ match the schema you've specified.
150
142
.. tip ::
151
143
152
144
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
154
150
155
151
Persisting Objects to the Database
156
152
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
157
153
158
154
Now that you have a ``Product `` object and corresponding ``product `` table,
159
155
you'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
161
157
bundle::
162
158
163
- // src/Acme/StoreBundle/ Controller/DefaultController .php
159
+ // src/AppBundle/ Controller/ProductController .php
164
160
165
161
// ...
166
- use Acme\StoreBundle \Model\Product;
162
+ use AppBundle \Model\Product;
167
163
use Symfony\Component\HttpFoundation\Response;
168
164
169
- public function createAction()
165
+ class ProductController extends Controller
170
166
{
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');
175
173
176
- $product->save();
174
+ $product->save();
177
175
178
- return new Response('Created product id '.$product->getId());
176
+ return new Response('Created product id '.$product->getId());
177
+ }
179
178
}
180
179
181
180
In 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
194
193
you've configured a route to display a specific ``Product `` based on its ``id ``
195
194
value::
196
195
196
+ // src/AppBundle/Controller/ProductController.php
197
+
197
198
// ...
198
- use Acme\StoreBundle \Model\ProductQuery;
199
+ use AppBundle \Model\ProductQuery;
199
200
200
- public function showAction($id)
201
+ class ProductController extends Controller
201
202
{
202
- $product = ProductQuery::create()
203
- ->findPk($id);
203
+ // ...
204
204
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
+ }
210
214
211
- // ... do something, like pass the $product object into a template
215
+ // ... do something, like pass the $product object into a template
216
+ }
212
217
}
213
218
214
219
Updating an Object
@@ -217,31 +222,37 @@ Updating an Object
217
222
Once you've fetched an object from Propel, updating it is easy. Suppose you
218
223
have a route that maps a product id to an update action in a controller::
219
224
225
+ // src/AppBundle/Controller/ProductController.php
226
+
220
227
// ...
221
- use Acme\StoreBundle \Model\ProductQuery;
228
+ use AppBundle \Model\ProductQuery;
222
229
223
- public function updateAction($id)
230
+ class ProductController extends Controller
224
231
{
225
- $product = ProductQuery::create()
226
- ->findPk($id);
232
+ // ...
227
233
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);
233
237
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
+ }
236
243
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
+ }
238
249
}
239
250
240
251
Updating an object involves just three steps:
241
252
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 ).
245
256
246
257
Deleting an Object
247
258
~~~~~~~~~~~~~~~~~~
@@ -257,16 +268,22 @@ Querying for Objects
257
268
Propel provides generated ``Query `` classes to run both basic and complex queries
258
269
without any work::
259
270
260
- \Acme\StoreBundle\Model\ProductQuery::create()->findPk($id);
271
+ use AppBundle\Model\ProductQuery;
272
+ // ...
273
+
274
+ ProductQuery::create()->findPk($id);
261
275
262
- \Acme\StoreBundle\Model\ ProductQuery::create()
276
+ ProductQuery::create()
263
277
->filterByName('Foo')
264
278
->findOne();
265
279
266
280
Imagine that you want to query for products which cost more than 19.99, ordered
267
281
from cheapest to most expensive. From inside a controller, do the following::
268
282
269
- $products = \Acme\StoreBundle\Model\ProductQuery::create()
283
+ use AppBundle\Model\ProductQuery;
284
+ // ...
285
+
286
+ $products = ProductQuery::create()
270
287
->filterByPrice(array('min' => 19.99))
271
288
->orderByPrice()
272
289
->find();
@@ -279,20 +296,26 @@ abstraction layer.
279
296
If you want to reuse some queries, you can add your own methods to the
280
297
``ProductQuery `` class::
281
298
282
- // src/Acme/StoreBundle/Model/ProductQuery.php
299
+ // src/AppBundle/Model/ProductQuery.php
300
+
301
+ // ...
283
302
class ProductQuery extends BaseProductQuery
284
303
{
285
304
public function filterByExpensivePrice()
286
305
{
287
- return $this
288
- ->filterByPrice(array('min' => 1000));
306
+ return $this->filterByPrice(array(
307
+ 'min' => 1000,
308
+ ));
289
309
}
290
310
}
291
311
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
293
313
``findAllOrderedByName() `` can be written without any effort::
294
314
295
- \Acme\StoreBundle\Model\ProductQuery::create()
315
+ use AppBundle\Model\ProductQuery;
316
+ // ...
317
+
318
+ ProductQuery::create()
296
319
->orderByName()
297
320
->find();
298
321
@@ -310,7 +333,7 @@ Start by adding the ``category`` definition in your ``schema.xml``:
310
333
<?xml version =" 1.0" encoding =" UTF-8" ?>
311
334
<database
312
335
name =" default"
313
- namespace =" Acme\StoreBundle \Model"
336
+ namespace =" AppBundle \Model"
314
337
defaultIdMethod =" native" >
315
338
316
339
<table name =" product" >
@@ -382,12 +405,14 @@ Saving Related Objects
382
405
383
406
Now, try the code in action. Imagine you're inside a controller::
384
407
408
+ // src/AppBundle/Controller/ProductController.php
409
+
385
410
// ...
386
- use Acme\StoreBundle \Model\Category;
387
- use Acme\StoreBundle \Model\Product;
411
+ use AppBundle \Model\Category;
412
+ use AppBundle \Model\Product;
388
413
use Symfony\Component\HttpFoundation\Response;
389
414
390
- class DefaultController extends Controller
415
+ class ProductController extends Controller
391
416
{
392
417
public function createProductAction()
393
418
{
@@ -418,21 +443,25 @@ Fetching Related Objects
418
443
~~~~~~~~~~~~~~~~~~~~~~~~
419
444
420
445
When 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
423
449
424
450
// ...
425
- use Acme\StoreBundle \Model\ProductQuery;
451
+ use AppBundle \Model\ProductQuery;
426
452
427
- public function showAction($id)
453
+ class ProductController extends Controller
428
454
{
429
- $product = ProductQuery::create()
430
- ->joinWithCategory()
431
- ->findPk($id);
455
+ public function showAction($id)
456
+ {
457
+ $product = ProductQuery::create()
458
+ ->joinWithCategory()
459
+ ->findPk($id);
432
460
433
- $categoryName = $product->getCategory()->getName();
461
+ $categoryName = $product->getCategory()->getName();
434
462
435
- // ...
463
+ // ...
464
+ }
436
465
}
437
466
438
467
Note, in the above example, only one query was made.
@@ -454,14 +483,14 @@ inserted, updated, deleted, etc).
454
483
455
484
To add a hook, just add a new method to the object class::
456
485
457
- // src/Acme/StoreBundle /Model/Product.php
486
+ // src/AppBundle /Model/Product.php
458
487
459
488
// ...
460
489
class Product extends BaseProduct
461
490
{
462
491
public function preInsert(\PropelPDO $con = null)
463
492
{
464
- // do something before the object is inserted
493
+ // ... do something before the object is inserted
465
494
}
466
495
}
467
496
@@ -488,8 +517,8 @@ Behaviors
488
517
---------
489
518
490
519
All 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 `_.
493
522
494
523
Commands
495
524
--------
0 commit comments