This is my code:
$get_all = Geo_Postal_us::findOrFail($postal);
With this query, Laravel tries to find the id field in the table.
I don't have an id field. I use the postal column as primary key.
How do you set the function to find value in postal column and not search from id column?
Thanks,
You could create the behaviour you are looking for with the following:
Geo_Postal_us::where('postal', $postal)->firstOrFail();
Laravel by default is searching for the "id" column inside the table if you are using find(). To avoid running into errors here and maybe later, you should always tell laravel that you did take another name for your primary field.
To do that, in your Geo_Postal_us just edit as the following:
class Geo_Postal_us extends Model
{
protected $primaryKey = 'postal'; //tell laravel to use 'postal' as primary key field
...
...
I ran into this issue within Voyager and it really drove me nuts :).
Hope this helps some people as they google the issue.
Related
Hi need your help to understand some feature in CakePHP.
I have a SQL Table : user.
I generate with bake the Model : UserTable.
In the action home() of my UsersController, i have this :
$t_Results = TableRegistry::get('User')->findByLogin('jdupont')->execute()->fetchAll('assoc');
debug($t_Results);
The query is generated by Cake and this code works well.
My question are :
Must i create the function findByLogin inside the Model or not ?
Is my code correct ?
Thanks for the help ;)
Yes you can create a findByLogin in your model but you don't have to.
Your code works but doesn't respect conventions.
In CakePHP 3
SQL tables are singular lowercase,
Table files has upper first letter and plural suffixed by Table,
Controllers are plural first letter upper and suffixed by Controller.
If you follow these conventions in your controller you can do this:
$t_Results = $this->Users->findByLogin('jdupont')->execute()->fetchAll('assoc');
debug($t_Results);
You don't have to use ->execute(). Query objects are lazily evaluated, execute will be called when you will use the request.
One of the quickest ways for you to check if your code is correct is to actually run it and see if it returns what you expect.
findByLogin() is a Cake dynamic finder so you don't need to define this method as Cake dynamically does this for you. You can prefix any camel-cased column name with findBy to query a table using that column.
You can use it like this:-
$t_Results = $this->Users->findByLogin('jdupont')->first();
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 a "production" table with field employee_id as a belongsTo relation to employees table.
The problem is my employees table uses field emp_appserial as primary key -as opposed to id field- (not every entry on employees table gets an id value, everyone gets auto increment emp_appserial)
I wonder if there is a way to use saveField using a field other than id to get to my record: (I mentioned I have records with no "id" value, only emp_appserial, which is pk)
$this->loadModel('Employees');
$this->Employees->id = $id;
$this->Employees->saveField('emp_hrnote', 'text to be saved');
I'd like to use:
$this->Employees->emp_appserial = $id;
instead of
$this->Employees->id = $id;
I that doable?
Aside from that, it may not be too late to re-design my tables, but I already have a lot of production data :-(
Thank you for any pointers.
The following should do the trick (btw, models should be singular):
class Employees extends Model {
public $primaryKey = 'emp_appserial';
}
If you don't set the $primaryKey attribute, it gets set to id: Source
Once you set that saveField() will use that field for the condition: Source
Edit: Just to make it clear, you would still use Model::$id to set the primary key value. Model::$id holds the primary key value, Model::$primaryKey holds the primary key field
Used
$this->Employee->updateAll(
array('Employee.emp_hrnote' => "$thetxt"),
array('Employee.emp_appserial' => $id)
);
As a workaround is just fine, however I wish I could solve my empty id issue... will post another issue with this on another post.
I have changed the fieldname parent_id to FldParentId in a Table admin_menus. I want to select all the sub menus under a particular parent_id. but it gives an notice like
"Notice (8): Undefined index: parent_id [CORE/cake/libs/model/model.php, line 2337]".
So my question is that can I change this fieldname from parent_id to FldParentId.Is that possible..or I have to keep this fieldname as parent_id??
Please help me out..I need to know dat..
Thanks in advance.
Since there is no option to overwrite the key to use for the find('threaded') method you need to keep the fieldname like the way CakePHP wants it or you could overwrite the method used by CakePHP in your AppModel.
Seecake/libs/model/model.php on line 2311 where you can find the _findThreaded function to see how this is working.
I would just rename the field if you have no other dependencies on it.
I use JPA->Hibernate. PlayFramework. I want to have relationship.
Category - 1:n -> Tag
Every category can have many tags, but tags do not know about it.
So, i do like this:
#Entity
public class Category ... {
#OneToMany
public List<Tag> tags = new LinkedList<Tag>();
}
I have test:
#Test
public void playWithTags() {
Tag tag1 = new Tag("tag1").save(); // managed by playframework
Category cat1 = new Category("cat1");
cat1.tags.add(tag1);
cat1.save();
// check if tag1 and cat1 were saved
assertEquals(1, Tag.count());
assertEquals(1, Category.count());
Category cat2 = new Category("cat2");
cat2.tags.add(tag1);
cat2.save();
}
The result is:
16:18:01,555 ERROR ~ Duplicate entry '1' for key 'tags_id'
16:18:01,555 ERROR ~ Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelp
....
java:908)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.sql.BatchUpdateException: Duplicate entry '1' for key 'tags_id'
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2020)
It seems that cat2.save() try to do more then it should
If if use merge() instead of save() it works good:
cat2.merge();
BUT WHY?
I have fixed the problem. The problem was in that, that I used NOT THAT annotation. So i just changed #OneToMany to #ManyToMany and voilĂ - No any restrictions anymore.
But if saying about the OneToMany then it seems there was a unique-restriction on database-level which prevented us to put not-unique values to tags_id. Therefore we could not put same tag to One category. I.e. it wanted One category for Many tags, but if tags were already 'used' - no way.. I tried to put unique=true/false in #JoinTable -> #JoinColumn - but it does not help. For me it's still strange, but at least current problem was fixed.
You're mixing up two concepts: Primary key and foreign key.
There can be only one PK but FK just means "there must be an element with this ID in some other table". FK doesn't constrain uniqueness.
[EDIT] Your problem is that you're mixing entities. How did you get the tag1 which is returned by save()?
This entity must be one which you get from Hibernate, not the result from new. Even if it looks insane, you must do this in save():
session.save(tag);
return session.load(tag.getId());
This way, you get an entity that is managed by Hibernate. Only when the entity is managed by Hibernate, Hibernate knows when it has to save the entity and when it has already been saved.
So when you do cat2.tags.add(tag1); in your example above, Hibernate thinks "oh, I don't know anything about this tag, it must be a new one".
And tries to save the tag again.