I have just set up DataMapper with CodeIgniter and written the models as required.
However I seem to have missed something, as when I run a query, DataMapper cannot see the table name override and thinks there is no table at all.
Funny thing is, if I remove the override, it works as it should (albeit with an error saying the auto-generated tabled doesnt exist).
Model Code:
class Activity extends Datamapper {
var $table = 'activity_log';
var $has_one = [
'user'
];
}
Controller Code:
$activity = new Activity(1);
Error:
Error Number: 1064
You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the right
syntax to use near 'WHERE `.`id` = 1' at line 2
SELECT * WHERE `.`id` = 1
As I mentioned above, if I remove var $tables = 'activity_log'; then it will defer back to looking for table 'activities' as it should.
Rules
DataMapper models must be named the singular version of the object
name, with an uppercase first letter. So for a user object, the
DataMapper model would be named User. The model should have a
corresponding table in the database named as the lowercase, pluralised
version of the object name. So for a DataMapper model named User, the
table would be named users. For a DataMapper model named Country, the
table would be named countries.
In most cases, the difference between the singular and plural version
of an object name is just a matter of adding the letter s on the end.
Your model should be named as Activity_log.
Docs.
Related
I have my class "Product_reviews", which is binded to the class "Products" like this:
Products.php:
public function product_reviews()
{
return $this->hasMany('App\Product_reviews');
}
Product_reviews.php:
public function products()
{
return $this->belongsTo('App\Products');
}
Foreign key for table "Product_reviews" is 'product_id'.
So, in the controller I'm trying to get all data:
$products = Products::with('product_reviews')->get();
And... I have an error saying that product_id can't be found:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'product_reviews.products_id' in 'where clause' (SQL: select * from `product_reviews` where `product_reviews`.`products_id` in (1, 2))
Correct me if I'm wrong, but I think the query builder is adding '_id' to the class' name. It can be fixed by going to the table "product_reviews" and changing 'product_id' by 'products_id'... Or maybe I could pass all classes' and tables' names to singular.
So my question is: What other options do I have in order to make the query builder know the proper column's name?
Your models should be named in the singular form, and then Laravel will not attempt to use the plural form of the column name in the generated SQL query.
In your case, the Products model should be called Product. Remember that a model represents one record in your database, so the singular form is correct.
You overwrote this behaviour by manually setting the foreign field in your $this->hasMany(..) relationship, which skirted around the issue, but didn't fix the underlying cause.
Additionally, you should avoid using snake_cased class names, as it violates PSR. Your Product_reviews model should be called ProductReview.
Ok, I got it:
In Products.php:
return $this->hasMany('App\Product_reviews');
I added 2 more parameters to the function hasMany, like this:
return $this->hasMany('App\Product_reviews','product_id','id');
These parameters specify the id's names.
This post really helped:
laravel-hasmany-and-belongsto-parameters
Anyhow I think it may be good in long terms to do what Davit and hktang say and rename my classes with singular names. Thanks for your answers.
I am studying Laravel Framework for few hours and i am trying to do what's being done in the tutorial i am watching. I am executing a query through routes.php and it's giving me a different output.
My database has only 1 table and it is named 'customer' and i have a model named 'customer' and a controller named 'CustomerController'
My routes.php code is this
Route::get('customer', function() {
$customer = FirstLaravelApplication\Customer::find(1);
echo '<pre>';
print_r($customer);
But the localhost is giving me an error and it says i don't have any 'customers' table, it automatically added a letter 's' in the end of the table instead of 'customer' only. i really don't have any 'customers' table i don't know why it is passing the wrong name of the table but my code only says 'customer'.
i would appreciate any help! Thanks all!
Laravel/Eloquent ORM uses this convention, as do many ORMs. They pluralize table names.
Open up the Customer.php model and add in:
class Customer extends Model {
// Add this
protected $table = 'customer';
However, it's usually easier to stick with the framework's conventions.
https://laravel.com/docs/5.3/eloquent#eloquent-model-conventions
I'm starting to learn Laravel. I've run through the example instructions from the site successfully and now I'm trying a second run through and I'm running into an issue.
I'm trying to connect to a database called zipCodes and has one table called zipCodeDetails.
In my Laravel project I have a model containing the following code:
<?php
class ZipCodeDetails extends Eloquent {}
And in my routes.php file I have the following code:
Route::get('zipCodes', function (){
$zipCodes = ZipCodeDetails::all();
return View::make('zipCodes')->with('zipCodes', $zipCodes);
});
The error I'm running into is when I try to load the URL:
http://localhost:8888/zipCodes
In my browser I'm getting the error code:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'zipcodes.zip_code_details' doesn't exist (SQL: select * from `zip_code_details`)
There's nothing written in my code where I define the database zipCodes as zipcodes or the table zipCodesDetails as zip_code_details. Something in laravel is changing the database and table names.
Does anyone know why this is happening and how I can prevent it? I don't want to just rename the database or table names because while that may get me by in testing it's not a viable solution in practice.
Thanks!
This is the behaviour that uses if no table is being explicitly defined. In your ZipCodeDetails class, you can set the table name that this model will be using.
class ZipCodeDetails extends Eloquent
{
protected $table = 'zipCodesDetails';
}
how can I access any table from database in my model?
For example, I have Indexcontroller and code inside it:
$results = $this->Index->query("SELECT COUNT(*) FROM my_own_table");
Error: Database table indices for model Index was not found.
So, as I understand, I can access only table with naming related to model/controller name. But what to do if I can't modify the table naming and I want to access it's data?
You're not limited to using a model that's directly associated with your controller (this is just default behaviour); you can use any model.
To achieve what you want, create a new model for this table, eg. MyOwnTable, and in your controller, you can add this property to the class:
public $uses = array('Index', 'MyOwnTable');
Now you can access MyOwnTable using CakePHP's built in ActiveRecord functionality:
$results = $this->MyOwnTable->find('count');
If you have other tables you want to access, simply create models for those and add them to the $uses property. (You can also use $this->loadModel('Model') inside the action if you prefer).
If you have a table name that isn't very readable (eg. my_tb_own_1_x or some such), you can call the model class something human readable (eg. MyTable), and add the $useTable property to the model:
public $useTable = 'my_tb_own_1_x';
/* and change the default primary key if you have an unusual one */
public $primaryKey = 'my_tb_own_1_x_idx_pk';
See the CakePHP manual for more info on how to change default model and controller behaviour:
1.3 - Model Attributes
2.0 - Model Attributes
1.3 - Controller Attributes
2.0 - Controller Attributes
Nope. You can access different tables. However, CakePHP stumbles over the fact that the table that is associated by default to the Index model doesn't exist.
In other words, the model Index expects a table 'indices' to exist (and an error is thrown when it doesn't). You can do one of two things:
Create a table indices
Add the following to your Index model: var $useTable = false;
If you have any use for an indices table I'd go with option 1. If you're not going to use the indices table, go with option 2.
If you go with either step 1 or 2, your example should start working.
I am trying to remove a table from CakePHP. All the tables were created with the cake bake function and I have removed the table from all the models. But when I remove the table from the database I get an error message:
Error: Database table channels_offers for model ChannelsOffer was not found.
Notice: If you want to customize this error message, create app/views/errors/missing_table.ctp
So how do I remove a table that was originally baked in?
Well, it appears that you still have a model called ChannelsOffer. You would need to add a property to your ChannelsOffer model. Here's an example
class ChannelsOffer extends AppModel {
// this tells the model not to use a table, alternatively you could supply your
// own table name here.
public $useTable = false;