Associations: Linking Models
Together
One of the most
powerful features of CakePHP is the ability to link relational mapping provided
by the model. In CakePHP, the links between models are handled through
associations.
Defining relations
between different objects in your application should be a natural process. For
example: in a recipe database, a recipe may have many reviews, reviews have a
single author, and authors may have many recipes. Defining the way these
relations work allows you to access your data in an intuitive and powerful way.
The purpose of this
section is to show you how to plan for, define, and utilize associations
between models in CakePHP.
While data can come
from a variety of sources, the most common form of storage in web applications is
a relational database. Most of what this section covers will be in that
context.
एसोसिएशन: एक साथ मॉडल जोड़ने
CakePHP की सबसे ताकतवर
विशेषताएं में से एक मॉडल द्वारा प्रदान किए गए संबंधपरक मानचित्रण को जोड़ने की
क्षमता है। केकपीएचपी में, मॉडल के बीच के
संबंध संघों के माध्यम से नियंत्रित होते हैं।
आपके आवेदन में विभिन्न
वस्तुओं के बीच संबंधों को परिभाषित करना एक प्राकृतिक प्रक्रिया होना चाहिए।
उदाहरण के लिए: एक नुस्खा डेटाबेस में, एक नुस्खा में कई समीक्षाएं हो सकती हैं, समीक्षाएं में एक लेखक है, और लेखकों में कई व्यंजन हैं इन संबंधों के तरीके को
परिभाषित करने से आप अपने डेटा को सहज और शक्तिशाली तरीके से एक्सेस कर सकते हैं।
इस खंड का उद्देश्य
केपीपीएचपी में मॉडलों के बीच संघों के लिए योजना, परिभाषित करना,
हालांकि डेटा विभिन्न
स्रोतों से आ सकता है, वेब अनुप्रयोगों
में भंडारण का सबसे सामान्य रूप एक संबंधपरक डेटाबेस है। इस खंड में शामिल अधिकांश
लोग उस संदर्भ में शामिल होंगे।
Relationship
Types
The four association types in CakePHP are:
hasOne, hasMany, belongsTo, and hasAndBelongsToMany (HABTM).
Relationship
|
Association
Type
|
Example
|
one to one
|
hasOne
|
A user has one profile.
|
one to many
|
hasMany
|
A user can have multiple recipes.
|
many to one
|
belongsTo
|
Many recipes belong to a user.
|
many to many
|
hasAndBelongsToMany
|
Recipes have, and belong to, many ingredients.
|
To further clarify which way around the associations are
defined in the models: If the table of the model contains the foreign key
(other_model_id), the relation type in this model is always a Model belongsTo OtherModel relation!
Associations are defined by creating a class variable
named after the association you are defining. The class variable can sometimes
be as simple as a string, but can be as complex as a multidimensional array
used to define association specifics.
मॉडल में संगठनों के
चारों ओर कौन से किन तरीकों को परिभाषित किया गया है, यह स्पष्ट करने के लिए: यदि मॉडल की मेज में विदेशी कुंजी
(अन्य_मॉडेल_आईडी) है, तो इस मॉडल में संबंध प्रकार हमेशा आदर्श मॉडल है अन्य
मॉडेल संबंध!
एसोसिएशनों को परिभाषित
किया जा रहा है संघ के नाम पर एक वर्ग चर बनाने के द्वारा परिभाषित कर रहे हैं।
वर्ग चर एक स्ट्रिंग के रूप में कभी-कभार सरल हो सकता है, लेकिन एक बहुआयामी सरणी के रूप में जटिल हो सकता है जो
संघीय विशेषताओं को परिभाषित करने के लिए उपयोग किया जाता था।
class User extends AppModel
{
public $hasOne = 'Profile';
public $hasMany = array(
'Recipe' => array(
'className' => 'Recipe',
'conditions' => array('Recipe.approved'
=> '1'),
'order' => 'Recipe.created DESC'
)
);
}
In the
above example, the first instance of the word ‘Recipe’ is what is termed an
‘Alias’. This is an identifier for the relationship, and can be anything you
choose. Usually, you will choose the same name as the class that it references.
However, aliases for each model must be unique
across the app. For example, it is appropriate to have:
उपरोक्त
उदाहरण में, शब्द 'रेसीपी' का पहला उदाहरण जिसे 'एलायस' कहा जाता है यह रिश्ते
के लिए एक पहचानकर्ता है, और आप चुन सकते हैं कुछ भी हो सकते हैं। आम तौर पर, आप उसी नाम को चुनते
हैं, जो वर्ग
को संदर्भ देते हैं। हालांकि, एप के लिए प्रत्येक मॉडल के उपनाम अद्वितीय होना चाहिए।
उदाहरण के लिए, यह उचित
है:
class
User extends AppModel {
public $hasMany = array(
'MyRecipe' => array(
'className' => 'Recipe',
)
);
public $hasAndBelongsToMany = array(
'MemberOf' => array(
'className' => 'Group',
)
);
}
class
Group extends AppModel {
public $hasMany = array(
'MyRecipe' => array(
'className' => 'Recipe',
)
);
public $hasAndBelongsToMany = array(
'Member' => array(
'className' => 'User',
)
);
}
but
the following will not work well in all circumstances:
लेकिन निम्नलिखित सभी परिस्थितियों में अच्छी तरह से काम नहीं करेगा:
class User extends AppModel {
public $hasMany = array(
'MyRecipe' => array(
'className' => 'Recipe',
)
);
public $hasAndBelongsToMany = array(
'Member' => array(
'className' => 'Group',
)
);
}
class
Group extends AppModel {
public $hasMany = array(
'MyRecipe' => array(
'className' => 'Recipe',
)
);
public $hasAndBelongsToMany = array(
'Member' => array(
'className' => 'User',
)
);
}
because here we have the alias ‘Member’
referring to both the User (in Group) and the Group (in User) model in the
HABTM associations. Choosing non-unique names for model aliases across models
can cause unexpected behavior.
CakePHP will automatically create links
between associated model objects. So for example in your User model
you can access the Recipe model as:
क्योंकि यहां हमारे पास एचएबीटीएम एसोसिएशन
में यूजर (ग्रुप में) और ग्रुप (यूजर) मॉडल दोनों का उपनाम 'सदस्य' है। मॉडलों में
मॉडल उपनाम के लिए गैर-अद्वितीय नाम चुनना अनपेक्षित व्यवहार हो सकता है।
CakePHP स्वचालित रूप
से जुड़े मॉडल ऑब्जेक्ट के बीच लिंक बना देगा। तो उदाहरण के लिए अपने यूजर मॉडल
में आप रेसिपी मॉडल तक पहुंच सकते हैं:
$this->Recipe->someFunction();
Similarly in your controller you can access an associated
model simply by following your model associations:
$this->User->Recipe->someFunction();
belongsTo
Now that we have Profile data access from
the User model, let’s define a belongsTo association in the Profile model in
order to get access to related User data. The belongsTo association is a
natural complement to the hasOne and hasMany associations: it allows us to see
the data from the other direction.
When keying your database tables for a
belongsTo relationship, follow this convention:
का है
अब जब कि हमारे पास उपयोगकर्ता मॉडल से प्रोफ़ाइल डेटा पहुंच है, तो संबंधित उपयोगकर्ता डेटा तक पहुंच प्राप्त करने के लिए, प्रोफ़ाइल मॉडल में एक संबद्धता संबद्धता को परिभाषित करें। संबंधित एसोसिएशन हैऑन और कई अन्य संगठनों के लिए एक प्राकृतिक पूरक है: यह हमें अन्य दिशाओं से डेटा देखने की अनुमति देता है।
संबंधित संबंधों के लिए अपने डेटाबेस तालिकाओं को कुंजीयन करते समय, इस सम्मेलन का पालन करें:
belongsTo: the current model
contains the foreign key.
Relation
|
Schema
|
Banana
belongsTo Apple
|
bananas.apple_id
|
Profile
belongsTo User
|
profiles.user_id
|
Mentor
belongsTo Doctor
|
mentors.doctor_id
|
We can
define the belongsTo association in our Profile model at /app/Model/Profile.php
using the string syntax as follows:
class
Profile extends AppModel {
public $belongsTo = 'User';
}
We
can also define a more specific relationship using array syntax:
class
Profile extends AppModel {
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
)
);
}
·
Possible keys for belongsTo association arrays include:
- className: the class
name of the model being associated to the current model. If you’re
defining a ‘Profile belongsTo User’ relationship, the className key should
equal ‘User’.
- foreignKey: the name of
the foreign key found in the current model. This is especially handy if
you need to define multiple belongsTo relationships. The default value for
this key is the underscored, singular name of the other model, suffixed
with _id.
- conditions: an array of
find() compatible conditions or SQL strings such as array('User.active' => true)
- type: the type of
the join to use in the SQL query. The default is ‘LEFT’, which may not fit
your needs in all situations. The value ‘INNER’ may be helpful (when used
with some conditions) when you want everything from your main and
associated models or nothing at all.
- fields: A list of
fields to be retrieved when the associated model data is fetched. Returns
all fields by default.
- order: an array of
find() compatible order clauses or SQL strings such as array('User.username' => 'ASC')
- counterCache: If set to true,
the associated Model will automatically increase or decrease the
“[singular_model_name]_count” field in the foreign table whenever you do
a save() or delete(). If it’s a string, then it’s the field name to use. The value in the
counter field represents the number of related rows. You can also specify
multiple counter caches by defining an array. See Multiple counterCache.
- counterScope: Optional
conditions array to use for updating counter cache field.
·
Once this association has been defined, find operations
on the Profile model will also fetch a related User record if it exists:
- संबद्ध एसोसिएशन एरे के लिए संभावित कुंजी में शामिल हैं:
- ClassName: मौजूदा मॉडल से संबंधित मॉडल का वर्ग नाम। यदि आप एक 'प्रोफ़ाइल के लिए संबद्ध उपयोगकर्ता' संबंध को परिभाषित कर रहे हैं, तो क्लासनाम की 'उपयोगकर्ता' के बराबर होना चाहिए
- विदेशी कि: वर्तमान मॉडल में मिली विदेशी कुंजी का नाम। यह विशेष रूप से आसान है यदि आपको एकाधिक संबंधों को परिभाषित करने की आवश्यकता है। इस कुंजी के लिए डिफ़ॉल्ट मान, दूसरे मॉडल का एक संक्षिप्त नाम है, जो कि _id के साथ चिपका हुआ है।
- परिस्थितियों: सरणी ('User.active'
=> true) जैसे () संगत स्थितियों या एसक्यूएल तारों की एक सरणी
- प्रकार: SQL क्वेरी में उपयोग करने के लिए जुड़ने का प्रकार। डिफ़ॉल्ट 'LEFT' है, जो आपकी आवश्यकताओं को सभी परिस्थितियों में फिट नहीं कर सकता है। मूल्य 'INNER' उपयोगी हो सकता है (जब कुछ शर्तों के साथ प्रयोग किया जाता है) जब आप अपने मुख्य और संबद्ध मॉडल से कुछ भी नहीं चाहते हैं या बिल्कुल नहीं।
- फ़ील्ड: संबद्ध मॉडल डेटा प्राप्त किए जाने पर प्राप्त की जाने वाली फ़ील्ड की एक सूची। डिफ़ॉल्ट रूप से सभी फ़ील्ड लौटाता है
- ऑर्डर: सरणी ('User.username' => 'एएससी') जैसे कि () संगत ऑर्डर क्लाज़ या एसक्यूएल स्ट्रिंग्स ढूंढें
- काउंटर कैश: यदि सही पर सेट किया जाता है, तो जब भी आप सहेजे () या हटाएं () करते हैं, तो संबंधित मॉडल स्वचालित रूप से विदेशी तालिका में "[singular_model_name] _count" फ़ील्ड में वृद्धि या घटा देगा। यदि यह एक स्ट्रिंग है, तो इसका उपयोग करने के लिए फ़ील्ड का नाम है। काउंटर फ़ील्ड में मान संबंधित पंक्तियों की संख्या का प्रतिनिधित्व करता है। आप सरणी को परिभाषित करके एकाधिक काउंटर कैश को भी निर्दिष्ट कर सकते हैं। मल्टीपल काउंटर कैश देखें
- CounterScope:
काउंटर कैश फ़ील्ड को अद्यतित करने के लिए उपयोग करने के लिए वैकल्पिक स्थितियां
- एक बार इस संघ की परिभाषा के बाद, प्रोफ़ाइल मॉडल पर कार्यवाही मिल जाए तो यह संबंधित उपयोगकर्ता रिकॉर्ड भी प्राप्त करेगी:
//Sample results from a $this->Profile->find() call.
Array
(
[Profile]
=> Array
(
[id]
=> 12
[user_id]
=> 121
[skill]
=> Baking Cakes
[created]
=> 2007-05-01 10:31:01
)
[User]
=> Array
(
[id]
=> 121
[name]
=> Gwoo the Kungwoo
[created]
=> 2007-05-01 10:31:01
)
)
counterCache -
Cache your count()
This feature helps you cache the count of
related data. Instead of counting the records manually via find('count'), the model itself tracks any addition/deletion towards the associated $hasMany model
and increases/decreases a dedicated integer field within the parent model
table.
The name of the field consists of the
singular model name followed by a underscore and the word “count”:
my_model_count
Let’s say you have a model called ImageComment and a
model called Image. You would add a new INT-field to the images table
and name it image_comment_count.
काउंटर कैचे - आपकी गिनती कैश करें ()
यह सुविधा आपको संबंधित डेटा की गणना कैश करने में मदद करती है। खोज ('गिनती') के माध्यम से मैन्युअल रूप से रिकॉर्ड की गिनती के बजाय, मॉडल स्वतः संबद्ध $ की ओर किसी भी अतिरिक्त / विलोपन को ट्रैक करता हैअधिक मॉडल है और पैरेंट मॉडल तालिका के भीतर एक समर्पित पूर्णांक फ़ील्ड को बढ़ता / घटता है।
फ़ील्ड के नाम में एकवचन मॉडल का नाम होता है जिसके बाद एक अंडरस्कोर होता है और शब्द
"गिनती" होता है:
my_model_count
मान लीजिए कि आपके पास इमेज कॉममेंट नामक एक मॉडल और एक मॉडल नामक मॉडल है। आप छवि तालिका में एक नया इंट-फ़ील्ड जोड़ देंगे और इसे image_comment_count नाम दें
Here are some more examples:
Model
|
Associated Model
|
Example
|
User
|
Image
|
users.image_count
|
Image
|
ImageComment
|
images.image_comment_count
|
BlogEntry
|
BlogEntryComment
|
blog_entries.blog_entry_comment_count
|
Once you
have added the counter field, you are good to go. Activate counter-cache in
your association by adding a counterCache key and set the value to true:
एक बार जब आप काउंटर फील्ड जोड़ते हैं, तो आप जाने के लिए अच्छा है एक काउंटर कैश कुंजी जोड़कर
अपने सहयोग में काउंटर कैश सक्रिय करें और मान को सही पर सेट करें:
class
ImageComment extends AppModel {
public $belongsTo = array(
'Image' => array(
'counterCache' => true,
)
);
}
From now on, every time you add or remove a ImageComment associated
to Image, the number within image_comment_count is adjusted automatically.
counterScope
You can also specify counterScope. It allows you to specify a simple condition which tells the model when
to update (or when not to, depending on how you look at it) the counter value.
अब से, हर बार जब आप इमेज से जुड़े इमेजमेंट को जोड़ या हटा दें, तो image_comment_count के भीतर की संख्या स्वचालित रूप से समायोजित की जाती है।
counterScope
आप counterScope को भी निर्दिष्ट कर सकते हैं। यह आपको एक साधारण स्थिति निर्दिष्ट करने की अनुमति देता है जो मॉडल को बताता है कि जब अपडेट करने के लिए (या जब नहीं, तो आप इसे कैसे देखते हैं) काउंटर मान
Multiple
counterCache
Since 2.0, CakePHP has supported having
multiple counterCache in a single
model relation. It is also possible to define a counterScope for each counterCache. Assuming you have a User model
and a Message model, and you
want to be able to count the amount of read and unread messages for each user.
एकाधिक काउंटर कैश
2.0 के बाद से, CakePHP ने एकल मॉडल रिलेशन में कई काउंटर कैश का समर्थन किया है। प्रत्येक काउंटर कैश के लिए काउंटरस्स्कोप को परिभाषित करना भी संभव है। यह मानते हुए कि आपके पास एक उपयोगकर्ता मॉडल और संदेश मॉडल है, और आप प्रत्येक उपयोगकर्ता के लिए पढ़ने और अपठित संदेशों की संख्या की गणना करना चाहते हैं।
Model
|
Field
|
Description
|
User
|
users.messages_read
|
Count
read Message
|
User
|
users.messages_unread
|
Count
unread Message
|
Message
|
messages.is_read
|
Determines
if a Message is
read or not.
|
With this setup, your belongsTo would
look like this:
class
Message extends AppModel {
public $belongsTo = array(
'User' => array(
'counterCache' => array(
'messages_read' => array('Message.is_read'
=> 1),
'messages_unread' => array('Message.is_read'
=> 0)
)
)
);
}
No comments:
Post a Comment