Maybe this is a simple question but I didn't find it in cookbook.
I am confused when name for some plural words with 'ies"
Example:
City -> Cities
Controller: CitiesController
Table: CitiesTable
Model: City ???? or Citie ???
Now both made error when I run the app. Error did't find model name.
Thank you for any answers and sorry if my English is too bad.
UPDATE June 28th 2016
I found the solution. In fact, I just kept their name:
Controller: CitiesController in src/Controller/CitiesController.php
Table: CitiesTable in src/Model/Table/CitiesTable.php
Model or Entity: City in src/Model/Entity/City.php
It works for me.
Thank for all.
General use of the controller/entity/table name is the singular form of the noun(in your case CityController, CityTable and City). This removes the confusions between the singular and plural.
Another good practice is that your tables in the DB to be named with the singular of the entity they represent (for example your table is city , therefore your Table class should be called 'CityTable') . So you can always relate the information in the source with the tables in the DB.
Update Aug 11th 2016
Hi all,
Sorry for long time to answer this. I was quite busy. I found out my answer. I didn't use the "city" table only. I used "m_cities" instead. (M means Master). So all my files and classes name are:
Model > Entity:
MCity.php
Class:
class MCity extends Entity{
...
}
Model > Table
MCitiesTable.php
Class:
class MCitiesTable extends Table
{
...
}
In the class MCity in file MCity.php. I defined the initialize with following content for declare the table name for CakePHP understand my table name.
parent::initialize();
//Define used table name in database
$this->table('m_cities');
So final content of this class is:
class MCity extends Entity
{
public function initialize(array $config)
{
parent::initialize();
//Define used table name in database
$this->table('m_cities');
}//end initialize
}//end class
All are worked OK for my project until now. Because of somebody didn't see my update in post so I re-update as answer for searching people.
Thank you all.
Related
I'm trying to get my Eloquent models to work. My current database is like this:
The tricky part is that for a given Environment and Project, there can be multiple Accesses. So it is possible i have something like this:
Note that both rows has the same environment_id and project_id.
Question 1 : Is my database well designed? Or should i have created a three-way pivot table (id, project_id, environment_id, access_id) ?
Question 2 : How can i fetch all environments associated with a project in my Project model? Right now it looks like this:
class Project extends Model
{
public function accesses(){
return $this->hasMany('App\Models\Access', 'project_id');
}
public function environments(){
// The missing part i can't get to work :(
}
}
I would sugest you add a separete table for the access, that way you won't have duplicate data or problems with password resets.
If you just want all the environments linked to a project you want a many to many or one to many relation with pivot.
public function environments()
{
return $this->belongsToMany('environment', 'environment_project');
// the first argument is the model you link to, the second the pivot table
}
models:
Environment: id, name
Project: id, name
Environment_project:id, environment_id, project_id, access_id
Access: id, username, password
edit, access on pivot
public function environments()
{
return $this->belongsToMany('environment', 'environment_project')->withPivot('username', 'password');
//now you can do project::find(1)->environments->pivot->username
}
After struggling with this inconvenience for a couple of weeks now, I've decided to open en now topic here. A topic that can help me, but I'm sure it will help some others with this same problem too!
I wonder how I should name the tables, controllers and models of a hasMany through table (thus with additional fields) and it's coupled tables. I tried to stick on the CakePHP naming conventions as discribed in it's cookbook, but this constantly gave me some "Object not found" errors. For practical reason, I'll show you my problem with a multiple-words named table. Perhaps that could be the reason of the problem? ;)
Situation
I have a fansite of a themepark and as you now, a themepark has many attractions. To ride an attraction, you must have a minimal height. Sometimes, small people can only ride it with an adult companion. But most of the time: you are allowed to ride the attraction because you just are tall enough ;)
Now I want to show the information of a specific attraction on my website. Name, content, photos, and so on. In addition to that information, I want to display my guests if they (or their kids) are tall enough to ride that attraction. It should appear like this way:
0m00 -> 1m00: not allowed
1m00 -> 1m30: allowed with an adult companion
1m30 -> 1m90: allowed
Database
I have two tables that are representing two objects: "attractions" & "attraction_accessibilities". In this case, I'm 100% sure the database names are correct.
Table "attraction_accessibilities" (id - name):
1 - Not allowed
2 - Allowed with an adult companion
3 - Allowed
Table "attractions" (id - name):
1 - Boomerang
2 - Huracan
3 - Los Piratas
4 - El Volador
...
Secondly, I should have another table between "attractions" and "attraction_accessibilities". This table should contain:
an id specific for each record
a link to the id of the "attractions" table (attraction_id)
a link to the id of the "attraction_accessibilities" table
(attraction_accessibility_id)
the additional information like "min-height" and "max-height"
I think I should name that table "attraction_accessibilities_attractions". It's a constriction of the two other tables, and I did it that way because CakePHP proposed it when you're making a HABTM association (http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#hasandbelongstomany-habtm).
But unfortunately, when I do call it that way, I've never succeeded to link those models in my application together.
Question
Is there anybody who've had the same problem but found a solution for it? If "yes": how should I name my database tables then and also important: how should I name my controller and model .php files?
Many thanks for the one who could help me and some other hopeless programmers ;)
If you use the HABTM relationship with unique set to keepExisting then you can name the table as you like and set the joinTable parameter according to he name you choosed
i.e. in your Attraction model
public $hasAndBelongsToMany = array(
'AttractionAccessibility' =>
array(
'joinTable' => 'attraction_accessibilities_attractions',
)
);
Instead if you're going to use the hasMany through relation then you can name the table as you like. In fact the so called "hasMany through" is just the concatenation of two hasMany relationships
so. If you name your table restrictions then
class Attraction extends AppModel {
public $hasMany = array(
'Restriction'
);
}
class AttractionAccessibility extends AppModel {
public $hasMany = array(
'Restriction'
);
}
class Restrictionextends AppModel {
public $belongsTo = array(
'Attraction ', 'AttractionAccessibility '
);
}
The structure of concerning tables is as follows (MySQL):
//Table Name : team
tid PK
team_name (varchar)
//Table Name : fixture
fid PK
home_team_id FK |_ both referenced to 'tid' from 'team' table
away_team_id FK |
My aim is to retrieve the team names. Considering this structure, I think I'll have to retrieve home_team_id and away_team_id and then do something like
Fixture::where('tid','=',$home_team_id)->get();
My question is, is this the correct way to accomplish what I aim to do?
and
should this be done from the controller? (if so, then I'll have to do two queries from same function)
First, rather than having your primary keys be tid and fid, just keep them both as id. This is not only best practice, but will allow you to more easily use Laravel's Eloquent ORM as it by default assumes your primary key column is named id.
Second thing, make sure your table names are in plural form. Although this is not necessary, the example I'm about to give is using Laravel defaults, and Laravel assumes they are in plural form.
Anyway, once you've 'Laravelized' your database, you can use an Eloquent model to setup awesome relationships with very minimal work. Here's what I think you'd want to do.
app/models/Team.php
class Team extends Eloquent {
// Yes, this can be empty. It just needs to be declared.
}
app/models/Fixture.php
class Fixture extends Eloquent {
public function homeTeam()
{
return $this->belongsTo('Team', 'home_team_id');
}
public function awayTeam()
{
return $this->belongsTo('Team', 'away_team_id');
}
}
Above, we created a simple model Team which Laravel will automatically look for in the teams database table.
Second, we created model Fixture which again, Laravel will use the fixtures table for. In this model, we specified two relationships. The belongsTo relationship takes two parameters, what model it is related to, in both cases here they are teams, and what the column name is.
Laravel will automatically take the value in away_team_id and search it against the id column in your teams table.
With just this minimal amount of code, you can then do things like this.
$fixture = Fixture::find(1); // Retrieves the fixture with and id of 1.
$awayTeam = $fixture->awayTeam()->first(); // var_dump this to see what you get.
$homeTeam = $fixutre->homeTeam()->first();
Then you can proceed as normal and access the column names for the tables. So say you have a 'name' column in the teams table. You can echo out the the home team name from the fixture like so.
$fixture = Fixture::find(1); // Get the fixture.
echo $fixture->homeTeam->name;
It's nearly 2AM, so there might be an error or two above, but it should work.
Make sure you check the docs for Eloquent, especially the bits relating to relationships. Remember to name your columns and tables in the way Laravel wants you to. If you don't, there are ways to specify your custom names.
If you want to get even more fancy, you can define the inverse relationship like this on your Team model.
app/models/Team.php
class Team extends Eloquent {
public function fixturesAtHome()
{
return $this->hasMany('Fixture', 'home_team_id');
}
public function fixturesAway()
{
return $this->hasMany('Fixture', 'away_team_id');
}
}
Then to get all of a particular team's home fixtures...
$team = Team::find(1); // Retreive team with id of 1;
$homeFixtures = $team->fixturesAtHome();
I have two domain classes in which one has a one to many relationship with the other
Class A
{
...
#NotNull
static hasMany = [bElements:B]
}
Class B
{
...
}
When I run the application, the relation table A_B is created and entries in A_B table are automatically added when user creates A objects. Then I've decided to change this relation, because I've noticed that it is better to have a relation between class A and class C, so class A now has
static hasMany = [cElements:C]
but when I create a new object of type A (after creation of some C objects), adding one or more objects of type C, in my database I don't see the entry into the A_C table, but only in A table.
Why do this beahavior happens? What must I control to resolve problem?
EDIT:
maybe it is needed some clarifications. The Class A is a class that describes an invoice and the class C is a class that describes the invoices items. So I need to give a one-to-many relationship between this two classes, but as described above, it does not work as expected...
EDIT 2:
I've noticed that maybe the problem depends on the fact that the field cElements in A object is null. In the view, I've described the cElements field as follows:
<g:select name="receiptItems" from="${HealthService.findAllByDoctor(Doctor.findBySecUser(new ReceiptController().getCurrentlyLoggedUser()))}"
multiple="multiple" optionKey="id"
optionValue="${{it.healthServiceType.healthService}}"
size="5" value="${receiptInstance?.healthServices*.id}" class="many-to-many"
onchange="${remoteFunction(
controller: 'Receipt',
action: 'sumReceiptItems',
params: '\'receiptItemsSelected=\' + jQuery(this).val()',
onSuccess: 'updateTotalAmount(\'totalAmount\', data, \'00000\')')}"/>
It is a multiple select. After each selection, with the remoteFunction, a method from controller is called to do some calculation and update the totalAmount field. It works well but, when save method is called, healthServices field is null...and I don't understand why...I will open another post to solve this issue (solved here)
If you declare a class like
Class A
{
...
#NotNull
static hasMany = [cElements:C]
}
Class C
{
static belongsTo= [a:A]
...
}
In this case it does not create A_C but if you declare it like
Class A
{
...
#NotNull
static hasMany = [cElements:C]
}
Class C
{
//no belongTo
...
}
then it creates A_C in database to map these fields id.
There is no need to have an intermediate table with A-B relations when you have one-to-many relation esablished. If relation was bidirectional (B class objects could have multiple A class objects) then the intermediate table would be useful.
Check your databse whether your B class objects contain pointers (foreign keys) to A class objects. If they do, your ORM decided to create one-to-many relationship and your A-B relations table is not used.
I would ditch the intermediate table for now and add the following to B class
static belongsTo = [parent:A]
(keep the hasMany in A):
This will create a bi-directional relationship from B to A (aka foreign key in B table). Make sure you are conscious of how cascading deletes are handled with belongsTo.
http://grails.org/doc/2.2.x/ref/Domain%20Classes/belongsTo.html
You mentioned pre-populating. Make sure you aren't violating any constraints. Bootstrap often fails silently. Add something like on your instance in question:
`
if (!b.save()) {
b.errors.each {
println it
}
}
`
After you get this relationship working, take a look at this talk if you need to refactor your relationship for gorm performance using an intermediary table. http://www.infoq.com/presentations/GORM-Performance
I have a table called entries with an associated model called Entry. I stepped through the Blog-tutorial on the CakePHP website. It states that the table-name does not need to be specified because it is computed from the models name. ( Post => posts).
I doubt CakePHP knows that Entry is a non-conform noun when it comes to its plural form. So how can I set the table my model uses? I think CakePHP would otherwise try to access the table entrys.
The answer to your question is to specify it inside your model.
$useTable = 'yourtablename'
Although, as Wooble noted, your doubts are wrong.
Cakephp 3, use this instead:
https://book.cakephp.org/3.0/en/orm/table-objects.html
class MyTable extends Table
{
public function initialize(array $config)
{
parent::initialize($config);
$this->setTable('my_table');
$this->setAlias('MyTable');
}
}