EDIT: It doesn’t work even if I make that change by hand, so the problem is somewhere else. I’m probably doing something stupid here, but it did work with the previous Gas ORM version.
EDIT2: Am I supposed to somehow define the foreign key here? service_type table has a column called id and service has type_id. Is this what breaks it? Why did it work in the previous version though?
I’m actually quite new to databases and ORM, so bear with me here.
From information you provide, let say you have it set up this way right now
1. Service entity
Table name : service
Model name : Model\Service
2. Service type entity
Table name : service_type
Model name : Model\Service_type
In Model\Service
// Because you dont have service_type_id field, // you should define the foreign key... public $foreign_key = array('\\model\\service_type' => 'type_id');
//... in relationship declaration 'service_type' => ORM::belongs_to('\\Model\\Service_type'),
In Model\Service_type
//... in relationship declaration 'service' => ORM::has_many('\\Model\\Service'),
From information you provide, let say you have it set up this way right now
1. Service entity
Table name : service
Model name : Model\Service
2. Service type entity
Table name : service_type
Model name : Model\Service_type
In Model\Service
// Because you dont have service_type_id field, // you should define the foreign key... public $foreign_key = array('\\model\\service_type' => 'type_id');
//... in relationship declaration 'service_type' => ORM::belongs_to('\\Model\\Service_type'),
In Model\Service_type
//... in relationship declaration 'service' => ORM::has_many('\\Model\\Service'),
Alright, thanks for the help!
What about the auto-generated version where it’s \Model\Service\Type and not \Model\Service_type?
Does the same apply to that or should it work without defining the foreign key?
What about the auto-generated version where it’s \Model\Service\Type and not \Model\Service_type?
Regarding the auto-generated thing, other member already asked similar questions, and i already explain in this post and this post. Personally, this convention make it easier for me to distinguish a general tables and a pivot tables. If it was within some folder, then it must be a pivot table
indCI - 22 March 2012 05:45 AM
Does the same apply to that or should it work without defining the foreign key?
Yes the same apply, except, you may need to also specify the table name on Model\Service\Type :
Another thing, I had to retrieve records that match a datetime BETWEEN two datetimes and a certain foreign key.
In the last version I used
$this->find_where( 'starting BETWEEN "' . $date . '" AND "' . $to_date . '" AND resource_id=' . $resource_id );
I’m not sure if that was best practice but it worked.
There doesn’t seem to be a find_where method in Gas 2 though.
How should I achieve this?
EDIT: Ah, figured it out. If anyone needs it, here’s how I wrote it now. (Unless there’s a better way to do it.)
ModelName::where( 'starting BETWEEN "' . $date . '" AND "' . $to_date . '"' )->find_by_resource_id( $resource_id );
EDIT2: Scratch that. It did not work it just translated to this. Still don’t know how to do it.
SELECT * FROM (`ModelName`) WHERE `resource_id` = 2
EDIT3: Alright I put it in a single CI AR query, so that works at least, but shouldn’t find_by_column be chainable with them? Or is all() the only gas method that’s chainable with CI query builder?
ModelName::where( 'starting BETWEEN "' . $date . '" AND "' . $to_date . ' 23:59:59" AND resource_id=' . $resource_id )->all();
I searched for this info but with no luck, how can i use Gas ORM 2 with HMCV (Modular Extension) i want to put my models in my modules and not keep them in a folder models in my application folder. How can i do that?
Thank you,
Dan
Khrome83 already pointed to the right section. For example you have “foo” and “bar” module, located in application/modules, you could have something like this :
If your modules located outside your application folder, just modify the location with an absolute path within your modules.
Thanks for the reply, the thing is that i can`t add every single module in the config path because i want to allow users to develop/add modules of their own, and that would mean that the path would have to change every time someone ads a module, can’t it be done like gas orm 1.x done it? give it a folder and search for models in that folder? Or is there any other way to do this?
Thanks
Edit 1:
i added in config/gas.php, created the models with gas orm
and i am trying to access it from the news controller:
public function migrate(){ // FINDER $all_users = Model\News::all(); var_dump($all_users); }
and i get this in my error log
[b][22-Mar-2012 12:45:11 UTC] PHP Fatal error: Class 'Model\News' not found in /home/bogdan/public_html/beta/system/cms/modules/news/controllers/news.php on line 81[/b]
EDIT3: Alright I put it in a single CI AR query, so that works at least, but shouldn’t find_by_column be chainable with them? Or is all() the only gas method that’s chainable with CI query builder?
ModelName::where( 'starting BETWEEN "' . $date . '" AND "' . $to_date . ' 23:59:59" AND resource_id=' . $resource_id )->all();
Yeah, thats the right way to do it. find_by_something is a convinience method to find some record(s) based by a specific field, and it is already contain a single where clause. Its not chainable with other where clause, but it does chainable with most of other CI query builder(limit, group_by etc).
find_where is removed, to avoid redundant API due the availability of any other where method which inherit from CI query builder.all is similar with get in CI query builder, so it could chainable with most of CI query builder.
and i am trying to access it from the news controller:
public function migrate(){ // FINDER $all_users = Model\News::all(); var_dump($all_users); }
and i get this in my error log
[b][22-Mar-2012 12:45:11 UTC] PHP Fatal error: Class 'Model\News' not found in /home/bogdan/public_html/beta/system/cms/modules/news/controllers/news.php on line 81[/b]
what am i doing wrong?
Thanks
Nothing wrong with the log. You couldn’t access something that not exists. From your configuration above Model\News is the root of your news modules, right? You supposed to have model like : application/modules/news/models/foo.php contain :
<?php namespace Model\News;
use \Gas\Core; use \Gas\ORM;
class Foo extends ORM { //... field and relationship declarations }
then you could call foo model from whereever controller within your application :
$foo = Model\News\Foo::all();
If, somehow you dont want to specify each of your module’s models, you still can do that. But maybe your naming convention will be slightly akward, i think you could have this on models_path :
Then, for example you have bar model on foo module :
<?php namespace Model\Module\Foo\Models;
use \Gas\Core; use \Gas\ORM;
class Bar extends ORM { //... field and relationship declarations }
And i think you could call bar model using :
$bar = Model\Module\Foo\Models\Bar::all();
Not looks natural right? But well, at least that work, if its what you need. Since HMVC is not a natural/native part of CI, i can’t think other solution than that, in your specific case.
This version use PHP 5 autoloader, so its more efficient rather than the previous version, which recursively scanning the model folder
awesome, i was forgetting to add the news class at the end, thanks for taking the time to explain it all to me, you`ve done great work, i fallowed gas orm since it`s first release, saw version 2.0 on github but the lack of documentation when i first saw the 2.0 version made me wait. It`s great that you had the time to develop this orm
Congratz.
Yes, this ORM still lack of documentation (compare to something like CI Datamapper). I know, LAZY IS OUR VIRTUE, but i was hoping everyone also look at the classes/source code (since i was put comments/annotations block everywhere, and i think that would be prety much helped), to get deeper knowledge how this ORM works, or what APIs available either in the core classes or/and in extension classes. I will try to answer, if one of you need some clarification on that.
However, i’ve just got some email from NetTut, replied to my Gas ORM tutorial pitching. That mean in near time, i will share some point regarding this ORM in those tutorial site. I would share most of important thing in this ORM, how you all should use this ORM in your CodeIgniter application and hopefully that tutorial could be a legacy for any CI developer who use this ORM
Would a wiki type user guide work?
People could share their knowledge and you could comment on best practices.
It’s not always clear from the source code what the intended use is, so a documentation and/or some examples help a lot if you’re new to these. Especially the examples.
There are hooks for saving and deleting records, to do something with it before it goes through, but is it possible to hook reading records?
I’m working with a database where names and descriptions are stored as serialized arrays of localized strings. When I read records from there, I have to unserialize it and choose the right locale. I would like to do this automatically somewhere before it goes to my model or whatever code is reading the records.
EDIT:
Answering myself again, after going through the source for a while it looks like I could use the __get property overloading.
When reading records and looping through them with foreach, like in the example in the CRUD section of the User Guide, the foreach will fail if only one row matched the query.
Do I have to manually check each time to see if it returned an object or an array, and place the object in an array if not?
Is there a simpler way to make sure I always get an array even if there is just one row?
Simply create a file in the application/libraries/gas/extension/result.php contain above snippet, then you can use it as follow :
$result = Model\ORM\User::result()->all();
// Easy way to debug over your result echo $result;
// Convert the instances into an array of instance $users = $result->as_array();
foreach ($users as $user) { // $user will be a typical Gas Instance }
// Convert all instance's record into various format $records_array = $result->to_array(); // assoc array $records_json = $result->to_json(); // JSON $records_xml = $result->to_xml(); // XML
// Convert all instance's record into Gas\Data object $records_data = $result->to_data();
$first_user = $records_data->get('data.0'); // Return the first index $first_user_name = $records_data->get('data.0.name'); // Return the first index name $some_user_name = $records_data->get('data.100.name', 'Default Name'); // And so on...
foreach ($skills as $s) { echo $s->name.'<br />'; foreach ($s->types() as $t){ echo $t->name.'<br />'; } foreach ($s->professions() as $p) { echo $p->name.'<br />'; } foreach ($s->weapons() as $w) { echo $w->name.'<br />'; } //wtf($s);
}
Outputs -
A PHP Error was encountered
Severity: Notice
Message: Trying to get property of non-object
Filename: views/welcome.php
Line Number: 69
Fatal error: Call to a member function types() on a non-object in /home/guildwar/public_html/application/views/welcome.php on line 70
Obviously, you are trying to itterate object there, not an array. Try :
// Here you are try to find one record $this->output->enable_profiler(TRUE); $skill = Model\Skills::find(1);
foreach ($skill->types() as $t) { // Do your job with $t here }
Dan Tdr - 21 March 2012 08:42 PM
Hey toopay,
I searched for this info but with no luck, how can i use Gas ORM 2 with HMCV (Modular Extension) i want to put my models in my modules and not keep them in a folder models in my application folder. How can i do that?
Thank you,
Dan
Khrome83 already pointed to the right section. For example you have “foo” and “bar” module, located in application/modules, you could have something like this :
If your modules located outside your application folder, just modify the location with an absolute path within your modules.
@toopay -
Thanks for the feedback.
So multiple objects are returned as a array because I am asking for all().
If I use find, it returns a object in the object…
So how can I make my code universal for reading 1 or many objects?
For example, if i have the same page to display 1 as I do many (the view) but the model either gets all or a limited number, even a specific entry, then I have to test to see if it’s a array before presenting, or should I do a conversion to make it a array with a single entry?