SitePoint Sponsor |
|
User Tag List
Results 26 to 50 of 58
Thread: ActiveRecord - dynamic way
-
Feb 10, 2006, 11:30 #26
- Join Date
- Jun 2004
- Location
- Copenhagen, Denmark
- Posts
- 6,157
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by 33degrees
-
Feb 10, 2006, 11:48 #27
Originally Posted by 33degrees
Originally Posted by thr
-
Feb 10, 2006, 11:51 #28
- Join Date
- Aug 2003
- Location
- Toronto
- Posts
- 300
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by kyberfabrikken
-
Feb 10, 2006, 14:41 #29
- Join Date
- Jan 2005
- Location
- Ireland
- Posts
- 349
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Maybe using __autoload you can make a hack to work-around this problem. Here is some code in theory that may help (completetly untested in the sense that it is completely unrun, no PHP interpetator immediately handy at the moment).
PHP Code:function __autoload($class)
{
// Simplified inclusion of class for example.
include($class .'.php');
// Check if class inherits from ActiveRecord
$class = new ReflectionClass($class);
if ($class->isSubclassOf(new ReflectionClass('ActiveRecord'))) {
// Add a setClassName to ActiveRecord implementation
$class::setClassName($class);
}
}
For people who a) already use __autoload and b) want to use ActiveRecord as described, adding this in may allow them to do so, then when (and if) the syntax is supported, all they will have to do is change __autoload.
The question is, though, does it work? I'll try it out myself when I get a chance.
-
Feb 10, 2006, 14:46 #30
- Join Date
- Jan 2004
- Location
- Oslo, Norway
- Posts
- 894
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
For what it's worth, this is the closest approximation I've found:
PHP Code:class ActiveRecord {
protected static function find($class,$id) {
// get stuff from the database
return new $class(/* stuff */);
}
}
class Post extends ActiveRecord {
public static function find($id) {
return parent::find('Post',$id);
}
}
$post = Post::find(1);
print_r($post);
/*
Output:
Post Object
(
)
*/
Dagfinn Reiersøl
PHP in Action / Blog / Twitter
"Making the impossible possible, the possible easy,
and the easy elegant" -- Moshe Feldenkrais
-
Feb 10, 2006, 15:09 #31
- Join Date
- Oct 2004
- Location
- Worcester
- Posts
- 138
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by thr
Where you put the finder logic doesn't really matter; static find methods or a separate finder are both fine. Of course, I could be wrong
-
Feb 10, 2006, 15:39 #32
- Join Date
- Jan 2004
- Location
- Oslo, Norway
- Posts
- 894
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by akrabat
-
Feb 10, 2006, 15:39 #33
Originally Posted by thr
Originally Posted by jayboots
-
Feb 10, 2006, 15:59 #34
- Join Date
- Jun 2004
- Location
- Copenhagen, Denmark
- Posts
- 6,157
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by 33degrees
You could have a generic finder, which can be used for the majority of classes, and just write specific finders for thoose special cases.
Or perhaps it would be a better approach to think the other way around. Have a generic record-class, and just implement a gateway (finder+attributes metadata) for each type. That's not the activerecord ofcourse, but if you want simplicity ?
-
Feb 10, 2006, 18:02 #35
Originally Posted by kyberfabrikken
-
Feb 10, 2006, 18:45 #36
- Join Date
- Jun 2004
- Location
- Copenhagen, Denmark
- Posts
- 6,157
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Luke Redpath
-
Feb 10, 2006, 19:26 #37
Originally Posted by kyberfabrikken
Originally Posted by kyberfabrikken
Originally Posted by kyberfabrikken
PHP Code:
class Model {
var $mapper;
var $meta_data;
var $data;
function Model($mapper, $meta_data) {
$this->mapper = $mapper;
$this->meta_data = $meta_data;
}
function save() {
$this->mapper->save($meta_data, $data);
}
}
-
Feb 10, 2006, 19:34 #38
Originally Posted by kyberfabrikken
-
Feb 10, 2006, 19:51 #39
- Join Date
- Aug 2003
- Location
- Toronto
- Posts
- 300
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by 33degrees
Originally Posted by 33degrees
-
Feb 10, 2006, 20:17 #40
- Join Date
- Jun 2004
- Location
- Copenhagen, Denmark
- Posts
- 6,157
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by 33degrees
Originally Posted by jayboots
Say I have a class ListController, which produce a table of records from a datasource. The natural approach for me would be something like this :
PHP Code:$lister =& new ListController($gateway);
echo $lister->execute();
I know that I could pass the classname rather than an actual object, and let the ListController instantiate the class itself (or pull it through a static factory/singleton), but that really makes me uncomfortable.
-
Feb 10, 2006, 21:00 #41
- Join Date
- Aug 2003
- Location
- Toronto
- Posts
- 300
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
I think I do it a little differently -- my finders return recordsets (plain arrays), not collections of or singular ARs.
$user = new ADC_User;
$all_users = $user->findAll();
If I need a specific user:
$user->find(array('id'=>'foo'));
I also have a few reflection methods on the AR class to let me inspect the requirements of the specific AR instance based on the model it is derived from.
The upshot is that if I had a Lister component, it wouldn't be responsible for acquiring the data -- it gets passed a normal recordset. I'll definately be using some of the arguments in this thread as input when I go to reevaluate my implementation, but so far I find it satisfactory for my needs
-
Feb 10, 2006, 21:05 #42
- Join Date
- Jun 2004
- Location
- Copenhagen, Denmark
- Posts
- 6,157
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by jayboots
Anyway - The point is not as much if such a widget is the best possible implementation, but rather that the ambigouity may cause confusion.
-
Feb 10, 2006, 22:12 #43
Originally Posted by kyberfabrikken
-
Feb 10, 2006, 22:16 #44
Originally Posted by kyberfabrikken
Code:posts = Post.find(:all) lister = ListController.new(posts) lister.execute
-
Feb 10, 2006, 22:21 #45
Originally Posted by kyberfabrikken
Code:@post = Post.new @lots_of_posts = Post.find(:all)
-
Feb 10, 2006, 22:40 #46
- Join Date
- Jun 2004
- Location
- Copenhagen, Denmark
- Posts
- 6,157
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Luke Redpath
-
Feb 10, 2006, 22:48 #47
- Join Date
- Jun 2004
- Location
- Copenhagen, Denmark
- Posts
- 6,157
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Luke Redpath
-
Feb 11, 2006, 02:52 #48
Originally Posted by kyberfabrikken
In any case, it's possible to have your cake and eat it, too. Ergo:
PHP Code:
class ActiveRecord {
function find() {
$args = func_get_args();
$finder = new Finder();
return call_user_func_array(array($finder, 'find'), $args);
}
}
-
Feb 11, 2006, 06:32 #49
- Join Date
- Jan 2005
- Location
- United Kingdom
- Posts
- 208
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
I've just finished a project at work in which I've used a dynamic ActiveRecord in this way. The AR provides insert, update and delete methods, finder methods are handled by the subclass of AR. The subclass passes some meta data to the AR method, which can generate the queries from the protected properties of the subclass.
PHP Code:class ActiveRecord
{
private static $db; // ADODB
public function save( $table, $primary )
{
// Called from subclass context
$props = get_object_vars( $this );
$this->db->Execute( ... );
}
}
class ValueObject extends ActiveRecord
{
const TABLE = 'SOME_TABLE';
const PRIMARY = 'PRIMARY_KEY';
protected $prop;
public function findByPrimaryKey( $pk )
{
$row = $this->db->Execute( ... );
$this->bless( $row ); // Like perl's bless
}
}
$vo = new ValueObject();
$vo->findByPrimaryKey( 1 );
$vo->set( 'prop', 1 );
$vo->save( ValueObject::TABLE, ValueObject::PRIMARY );
-
Feb 11, 2006, 06:57 #50
Generic mappers is NOT the way to go imho, because it requires you to put all your special finder-methods in one big class.
Bookmarks