Skip to content

Instantly share code, notes, and snippets.

@joeytrapp
Last active December 27, 2015 10:39
Show Gist options
  • Save joeytrapp/7312311 to your computer and use it in GitHub Desktop.
Save joeytrapp/7312311 to your computer and use it in GitHub Desktop.
Very basic SeedShell, with default and dev files along with ability to specify file manually. Also has a firstOrCreate helper to make creating seed records idempotent.
<?php
$User = ClassRegistry::init('User');
$this->firstOrCreate(
$User,
array('email' => 'admin@example.com'),
array('first_name' => 'Admin', 'last_name' => 'Admin')
);
<?php
$User = ClassRegistry::init('User');
$user = $User->find('first');
$Post = ClassRegistry::init('Post');
$this->firstOrCreate(
$Post,
array('title' => 'Example Title 1'),
array('body' => 'Lorem ipsum', 'user_id' => $user['User']['id'])
);
<?php
class SeedShell extends AppShell {
public $seedFile = 'seed.php';
public $seedDevFile = 'seed_dev.php';
public function main() {
$this->includeFile($this->absolutePath($this->getFile()));
}
public function init() {
$this->existsOrCreate($this->absolutePath($this->getFile()));
}
public function getOptionParser() {
$parser = parent::getOptionParser();
$parser->addOption('dev', array(
'boolean' => true,
'help' => 'Use the default dev file instead of the default'
));
$parser->addOption('file', array(
'help' => 'Manually specify the file that should be used'
));
return $parser;
}
public function firstOrCreate($Model, $conditions, $data = array()) {
$record = $Model->find('first', array('conditions' => $conditions));
if (!empty($record)) {
$Model->create($data + $conditions);
if ($Model->save()) {
$record = $Model->read();
} else {
$cond = var_export($conditions);
$this->out("Failed to create {$Model} record for conditions:\n\n{$cond}");
exit();
}
}
return $record;
}
private function getFile() {
$file = $this->seedFile;
if (isset($this->params['file']) && !empty($this->params['file'])) {
$file = $this->params['file'];
} else if ($this->params['dev']) {
$file = $this->seedDevFile;
}
return $file;
}
private function includeFile($file) {
include $file;
}
private function existsOrCreate($file) {
if (!file_exists($file)) {
file_put_contents($file, "<?php\n\n");
}
}
private function absolutePath($file) {
return APP . DS . 'Config' . DS . $file;
}
}
@beporter
Copy link

beporter commented Nov 5, 2013

So I'm understanding things properly, seed.php and seed_dev.php are examples of hand-written files here, right? Not part of the "package" or auto-generated in any way?

If I recall, the process with the Rails seeds is that you write Rails code yourself to populate the tables, with a small stub program that can execute them for you. So in the same vein, this is an efficient/lean Shell that only has the job of processing any hand-written seeds the developer has created themselves.

@joeytrapp
Copy link
Author

Correct. The idea is that within the seed.php or seed_dev.php (or any seed_*.php file you specify with --file) can be any code necessary to build the data needed. Devs could build big arrays of data that they loop through or they could make a few functions that generate some dummy data. The only thing it tries to enforce is the difference between data that needs to exist in every env (seed.php) and data that only needs to exist for developers who are building up the app for the first time (seed_dev.php).

@ricog
Copy link

ricog commented Nov 5, 2013

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment