Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

Я думаю, что непонимание того, что такое "модель", отчасти вызвано тем же (чрезмерным) шумом "MVC", не проводя с ним много понимания самих понятий. Кажется, что пустым "AJAX" является, или даже проще, "Web 2.0". К лучшему или к худшему, многие детишки script прыгнули на вагон MVC, а так как простые сценарии howtos и example не намного больше, чем сказать вам, чтобы вы поместили свой код базы данных в "модель", неправильное использование этого поскольку только абстракция базы данных стала обычным явлением. Теперь вы читаете сообщения по всему Интернету, называя это "нечистым", "грязным", "хакерским", чтобы поместить любую бизнес-логику в модель. Это НЕПРАВИЛЬНО. Дезинформировали.

Простым примером является думать о внешних ключах: даже если вы хотите, чтобы ваша "модель" была моделью базы данных, если вы хотите быть "чистой", "правильной" или какой у вас, вы действительно должны обеспечивать соблюдение ссылочной целостности. Благодаря отсутствию реальной поддержки внешнего ключа в MySQL на протяжении многих лет, веб-приложения выросли без всякого беспокойства по поводу ссылочной целостности вообще. Я полагаю, подходит для образа жизни script. Во всяком случае, даже при таком упрощенном представлении о модели, чтобы иметь возможность поддерживать внешний ключ, модель должна работать с другими (или, особенно, если инфраструктура, такая как 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;
   }

Ответ 3

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

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/

Ответ 4

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

Ответ 5

В подобных ситуациях в 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);



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

Ответ 6

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

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

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

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

Ответ 7

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

Ответ 8

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