Доступ к моделям CodeIgniter в других моделях

Раньше считалось, что в модели CodeIgniter вы не можете получить доступ к другой модели.

$this->load->model('bar'); $this->bar->something(); 

Это все еще актуально или они изменили его?

Solutions Collecting From Web of "Доступ к моделям CodeIgniter в других моделях"

Это некоторые ОЧЕНЬ длительные ответы на простой вопрос.

Короткий ответ: теперь это полностью поддерживается. Перекрестная нагрузка, если вам это нравится!

Я категорически не согласен с тем, что «модель» должна инкапсулировать только таблицу базы данных с помощью простых операций CRUD. Как отмечается в статье в Википедии:

http://en.wikipedia.org/wiki/Model-view-controller#As_a_design_pattern

… этот прикладной уровень предназначен для того, чтобы делать больше, чем просто действовать как абстракция отдельной таблицы базы данных. Подумайте о значении слова «контроллер» – он должен действовать скорее как директор, а не как само приложение. «Модель» это место для бизнес-логики. Большинство приложений большого масштаба фактически хранят большую часть своей бизнес-логики в самой базе данных (в виде триггеров, хранимых процедур, внешних ключей и т. Д.).

Я думаю, что непонимание того, что такое «модель», отчасти вызвано тем же (чрезмерным) шумом «MVC», не принося с собой много понимания самих понятий. Кажется, что пустым «AJAX» является, или даже проще, «Web 2.0». К лучшему или худшему, многие сценаристы-детишки прыгнули на вагон MVC, и поскольку простые сценарии howtos и example не делают ничего, кроме как сказать вам, что ваш код базы данных находится в «модели», неправильное использование этого слоя как только абстракция базы данных стала обычным явлением. Теперь вы читаете сообщения по всему Интернету, называя это «нечистым», «грязным», «хакерским», чтобы поместить любую бизнес-логику в модель. Это неверно. Дезинформировали.

Простой пример – подумать о внешних ключах: даже если вы хотите, чтобы ваша «модель» была моделью базы данных , если вы хотите быть «чистым», «правильным» или что у вас есть, вы действительно должны применять ссылочную целостность , Благодаря отсутствию реальной поддержки внешнего ключа в MySQL на протяжении многих лет, веб-приложения выросли без всякого беспокойства по поводу ссылочной целостности вообще. Думаю, подходит для сценария kiddie. Во всяком случае, даже при таком упрощенном представлении о модели, чтобы иметь возможность поддерживать внешний ключ, модель должна работать с другими (или, особенно, если инфраструктура, такая как CodeIgniter, не позволяет вам это делать, вам приходится писать запросы к другим таблицы, иногда дублирующие запросы в другом месте – это плохой стиль).

Поэтому я считаю, что это недостаток CodeIgniter. Я понимаю, что это может быть нелегкое решение, но это, безусловно, неутешительный контроль.

Итак, что я сделал, это взять пример кода выше и отвлечь его в помощнике, чтобы теперь у меня была функция, которая почти идентична нормальной функциональности $ this-> load-> model (). Вот он (помещаем его в помощник, который автоматически загружается, и вы можете использовать его в любой модели):

 /** * * Allow models to use other models * * This is a substitute for the inability to load models * inside of other models in CodeIgniter. Call it like * this: * * $salaries = model_load_model('salary'); * ... * $salary = $salaries->get_salary($employee_id); * * @param string $model_name The name of the model that is to be loaded * * @return object The requested model object * */ function model_load_model($model_name) { $CI =& get_instance(); $CI->load->model($model_name); return $CI->$model_name; } 

Это возможно, но не идеально и считается плохим и более «быстрым решением», чем идеальная или чистая реализация.

 class Location extends Model{ public function get($ID){ // Get main CI object handle and load model $CI =& get_instance(); $CI->load->model('LocationType'); // Call new model functions using handle to main CI object $CI->LocationType->setID($result->LocationTypeID); $CI->LocationType->setTitle($result->TypeTitle); $this->_locationType = $CI->LocationType; //Other Stuff } } 

В любое время, когда вы используете основной объект CI, например, это, вероятно, плохая идея. Постарайтесь переосмыслить свой макет и просто передать данные в / из вашего контроллера на модели.

http://codeigniter.com/forums/viewthread/69833/

Вы можете загружать модели из моделей, как говорит Phil Sturgeon, но вы должны быть осторожны с зависимостями, если вы загружаете модели в конструктор модели: если модель A использует модель B, а модель B использует модель A, когда вы пытаетесь загрузить один или другие, вы войдете в бесконечный цикл.

В ситуациях, подобных этому в Code Igniter, я предпочитаю одну из двух обязанностей:

1) Иметь атрибут и сеттер модели следующим образом:

 class X extends Model { var $Y_model; public function setY($Y) { $this->Y_model = $Y; } public function doItRightNow($a,$b) { $list = $this->Y_model->getSomeList($a,$b); // ... } // ... } 

И затем используйте этот сеттер перед другими методами, чтобы дать экземпляр другой модели, чтобы он мог использоваться методами.

 $this->load->model('X'); $this->load->model('Y'); $this->X->setY($this->Y); $this->X->doItRightNow($something,$somethingElse); 

2) Чтобы иметь параметр в методе, с помощью которого я дам экземпляр другой модели из контроллера.

 class X extends Model { public function doItRightNow($a,$b,$Y_model) { $list = $Y_model->getSomeList($a,$b); // ... } // ... } 

И используйте его вот так:

  $this->load->model('X'); $this->load->model('Y'); $this->X->doItRightNow($something,$somethingElse,$this->Y); 

Я думаю, что это более чистые возможности.
Какой способ использовать зависит от того, сколько методов нужно получить в другой модели. Если есть один или два, может быть лучше указать его как параметр метода. Если больше – я думаю, что лучше иметь атрибут класса и сеттер.
И элегантным способом вы можете дать одну модель или другую в зависимости от какого-либо условия – если они оба частично реализуют один и тот же интерфейс с возвращенными такими же данными (это редко полезно, но иногда это может быть полезно).

Я думаю, что, как правило, лучше писать библиотеки, которые обращаются к моделям, а затем включать библиотеки в вашу модель, если это необходимо.

Например, если вам нужно проверить, разрешено ли кому-либо проходить определенное действие CRUD, вы можете включить любую используемую библиотеку проверки подлинности (ее, вероятно, автоматически включали в большинстве случаев). Вы не обязательно хотите напрямую обращаться к модели – это просто кажется грязным и неправильным.

Я думаю, что предпочтительный способ – сделать то, что вам нужно сделать в вашем контроллере, и передать результаты из метода (ов) одной модели, если нужно, методу вашей другой модели.

Несмотря на это, я не понимаю, почему невозможно было бы включить одну модель в другую. Я не думаю, что вы можете сделать это с синтаксисом, который вы показываете. Вы должны были бы сделать это каким-то другим запутанным способом. В любом случае, ИМО, плохой практикой является включение модели непосредственно в другую модель.

В CI 2.0 вы можете просто вызвать одну модель напрямую из другой.

Лучше создать вспомогательную функцию вместо вызова функции из другой модели, чтобы ее можно было использовать в двух моделях одновременно, и код можно использовать повторно.