У меня есть модель с отношением, и я хочу создать экземпляр нового объекта типа отношений.
Пример. У человека есть компания, и у меня есть объект person: теперь я хочу создать компанию-объект.
- CodeIgniter в отчетах об ошибках 1 и 1
- Исключение PHP activerecord: базовая таблица или представление не найдены
- Laravel 4 с Data Mapper?
- Как запросить с активной записью в codeigniter для дат между указанными временами
- PHP ActiveRecord: как добавить несколько условий?
- PHP ActiveRecord, как проверить успешность соединения с базой данных?
Класс companyobject определен в отношении, поэтому я не думаю, что мне нужно «знать» этот класс, но я должен попросить человека-объекта предоставить мне новый экземпляр компании типа? Но я не знаю, как это сделать.
Это – я думаю – тот же вопрос, что и объект новой модели, через ассоциацию , но я использую PHPActiveRecord , а не рубиновый.
person
суперкласса, и у двух детей есть свое отношение к типу объекта компании. Мне нужно создать экземпляр правильного класса у абстрактного человека.
static $has_one
является получение его непосредственно из static $has_one
массива static $has_one
:
$class = $this::$has_one[1]['class_name']; $company = new $class;
Конечно, число с жестким кодом, конечно, может быть устранено путем поиска имени ассоциации в массиве, но это все еще довольно уродливо.
Вы также можете использовать build_association()
в классах отношений.
Самый простой способ использовать это через __call модели, т. Е. Если ваше отношение – это что-то вроде компании $person->company
, то вы можете создать экземпляр компании с помощью
$company = $person->build_company()
Обратите внимание, что это НЕ также приведет к «соединению» между вашими объектами ( $person->company
не будет установлена).
В качестве альтернативы вместо build_company()
вы можете использовать create_company()
, который сохранит новую запись и свяжет ее с $ person
В PHPActiveRecord у вас есть доступ к массиву отношений. Отношение должно иметь имя, которое вам НЕОБХОДИМО ЗНАТЬ ИМЯ СВЯЗИ / АССОЦИАЦИИ, ВЫ ХОТИТЕ . Это не должно быть имя класса, но имя класса модели, о которой вы говорите, должно быть явно указано в отношении. Просто базовый пример без проверки ошибок или подробных отношений db, таких как привязка таблицы или имени столбца внешнего ключа:
class Person extends ActiveRecord\Model { static $belongs_to = array( array('company', 'class_name' => 'SomeCompanyClass') ); //general function get a classname from a relationship public static function getClassNameFromRelationship($relationshipName) foreach(self::$belongs_to as $relationship){ //the first element in all relationships is it's name if($relationship[0] == $relationshipName){ $className = null; if(isset($relationship['class_name'])){ $className = $relationship['class_name']; }else{ // if no classname specified explicitly, // assume the clasename is the relationship name // with first letter capitalized $className = ucfirst($relationship); } return $className } } return null; } }
Для этой функции, если у вас есть объект person и хотите, чтобы объект, определенный отношениями «компания», использовал:
$className = $person::getClassNameFromRelationship('company'); $company = new $className();
В настоящее время я использую ниже решение.Это фактическое решение, а не$has_one[1]
hack, о котором я упоминал в вопросе.Если в phpactiverecord есть метод, я буду чувствовать себя очень глупо, разоблачающе себя.Но, пожалуйста, докажите мне глупость, поэтому мне не нужно использовать это решение: DЯ глуп. Ниже функциональность реализуется вызовом create_associationname, на что отвечает @Bogdan_D
\ActiveRecord\Model
. В моем случае есть класс между нашими классами и этой моделью, которая содержит дополнительные функции, подобные этому, поэтому я разместил его там.
Это две функции:
public function findClassByAssociation($associationName)
has_many
, belongs_to
и has_one
) для ассоциации findClassFromArray
если найдена ассоциация. $person->findClassByAssociation('company');
private function findClassFromArray($associationName,$associationArray)
Источник:
/** * Find the classname of an explicitly defined * association (has_one, has_many, belongs_to). * Unsure if this works for standard associations * without specific mention of the class_name, but I suppose it doesn't! * @todo Check if works without an explicitly set 'class_name', if not: is this even possible (namespacing?) * @todo Support for 'through' associations. * @param String $associationName the association you want to find the class for * @return mixed String|false if an association is found, return the class name (with namespace!), else return false * @see findClassFromArray */ public function findClassByAssociation($associationName){ //$class = $this::$has_one[1]['class_name']; $that = get_called_class(); if(isset($that::$has_many)){ $cl = $this->findClassFromArray($associationName,$that::$has_many); if($cl){return $cl;} } if(isset($that::$belongs_to)){ $cl = $this->findClassFromArray($associationName,$that::$belongs_to); if($cl){return $cl;} } if(isset($that::$has_one)){ $cl = $this->findClassFromArray($associationName,$that::$has_one); if($cl){return $cl;} } return false; } /** * Find a class in a php-activerecord "association-array". It probably should have a specifically defined class name! * @todo check if works without explicitly set 'class_name', and if not find it like standard * @param String $associationName * @param Array[] $associationArray phpactiverecord array with associations (like has_many) * @return mixed String|false if an association is found, return the class name, else return false * @see findClassFromArray */ private function findClassFromArray($associationName,$associationArray){ if(is_array($associationArray)){ foreach($associationArray as $association){ if($association['0'] === $associationName){ return $association['class_name']; } } } return false; }
,/** * Find the classname of an explicitly defined * association (has_one, has_many, belongs_to). * Unsure if this works for standard associations * without specific mention of the class_name, but I suppose it doesn't! * @todo Check if works without an explicitly set 'class_name', if not: is this even possible (namespacing?) * @todo Support for 'through' associations. * @param String $associationName the association you want to find the class for * @return mixed String|false if an association is found, return the class name (with namespace!), else return false * @see findClassFromArray */ public function findClassByAssociation($associationName){ //$class = $this::$has_one[1]['class_name']; $that = get_called_class(); if(isset($that::$has_many)){ $cl = $this->findClassFromArray($associationName,$that::$has_many); if($cl){return $cl;} } if(isset($that::$belongs_to)){ $cl = $this->findClassFromArray($associationName,$that::$belongs_to); if($cl){return $cl;} } if(isset($that::$has_one)){ $cl = $this->findClassFromArray($associationName,$that::$has_one); if($cl){return $cl;} } return false; } /** * Find a class in a php-activerecord "association-array". It probably should have a specifically defined class name! * @todo check if works without explicitly set 'class_name', and if not find it like standard * @param String $associationName * @param Array[] $associationArray phpactiverecord array with associations (like has_many) * @return mixed String|false if an association is found, return the class name, else return false * @see findClassFromArray */ private function findClassFromArray($associationName,$associationArray){ if(is_array($associationArray)){ foreach($associationArray as $association){ if($association['0'] === $associationName){ return $association['class_name']; } } } return false; }
,/** * Find the classname of an explicitly defined * association (has_one, has_many, belongs_to). * Unsure if this works for standard associations * without specific mention of the class_name, but I suppose it doesn't! * @todo Check if works without an explicitly set 'class_name', if not: is this even possible (namespacing?) * @todo Support for 'through' associations. * @param String $associationName the association you want to find the class for * @return mixed String|false if an association is found, return the class name (with namespace!), else return false * @see findClassFromArray */ public function findClassByAssociation($associationName){ //$class = $this::$has_one[1]['class_name']; $that = get_called_class(); if(isset($that::$has_many)){ $cl = $this->findClassFromArray($associationName,$that::$has_many); if($cl){return $cl;} } if(isset($that::$belongs_to)){ $cl = $this->findClassFromArray($associationName,$that::$belongs_to); if($cl){return $cl;} } if(isset($that::$has_one)){ $cl = $this->findClassFromArray($associationName,$that::$has_one); if($cl){return $cl;} } return false; } /** * Find a class in a php-activerecord "association-array". It probably should have a specifically defined class name! * @todo check if works without explicitly set 'class_name', and if not find it like standard * @param String $associationName * @param Array[] $associationArray phpactiverecord array with associations (like has_many) * @return mixed String|false if an association is found, return the class name, else return false * @see findClassFromArray */ private function findClassFromArray($associationName,$associationArray){ if(is_array($associationArray)){ foreach($associationArray as $association){ if($association['0'] === $associationName){ return $association['class_name']; } } } return false; }
,/** * Find the classname of an explicitly defined * association (has_one, has_many, belongs_to). * Unsure if this works for standard associations * without specific mention of the class_name, but I suppose it doesn't! * @todo Check if works without an explicitly set 'class_name', if not: is this even possible (namespacing?) * @todo Support for 'through' associations. * @param String $associationName the association you want to find the class for * @return mixed String|false if an association is found, return the class name (with namespace!), else return false * @see findClassFromArray */ public function findClassByAssociation($associationName){ //$class = $this::$has_one[1]['class_name']; $that = get_called_class(); if(isset($that::$has_many)){ $cl = $this->findClassFromArray($associationName,$that::$has_many); if($cl){return $cl;} } if(isset($that::$belongs_to)){ $cl = $this->findClassFromArray($associationName,$that::$belongs_to); if($cl){return $cl;} } if(isset($that::$has_one)){ $cl = $this->findClassFromArray($associationName,$that::$has_one); if($cl){return $cl;} } return false; } /** * Find a class in a php-activerecord "association-array". It probably should have a specifically defined class name! * @todo check if works without explicitly set 'class_name', and if not find it like standard * @param String $associationName * @param Array[] $associationArray phpactiverecord array with associations (like has_many) * @return mixed String|false if an association is found, return the class name, else return false * @see findClassFromArray */ private function findClassFromArray($associationName,$associationArray){ if(is_array($associationArray)){ foreach($associationArray as $association){ if($association['0'] === $associationName){ return $association['class_name']; } } } return false; }