代码之家  ›  专栏  ›  技术社区  ›  Ali

访问其他模型中的CodeIgniter模型

  •  38
  • Ali  · 技术社区  · 16 年前

    以前,在一个CodeIgniter模型中,你不能访问另一个模型。

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

    这是否仍然有效,或者他们更改了它?

    8 回复  |  直到 8 年前
        1
  •  68
  •   Phil Sturgeon    14 年前

    对于一个简单的问题,这些答案是很长的。

    简短回答: 现在完全支持这一点。如果你喜欢的话,交叉装载吧!

        2
  •  39
  •   oribani    15 年前

    我强烈反对“模型”只应该用简单的CRUD操作封装数据库表的观点。如维基百科文章所述:

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

    …该应用程序层的目的不仅仅是作为单个数据库表抽象。想想“控制器”这个词的含义——它应该更多地作为一个主管,而不是作为其本身的整个应用程序。“模型” 一个商业逻辑的地方。事实上,大多数大型应用程序在数据库本身(以触发器、存储过程、外键等形式)中保存了大部分业务逻辑。

    我认为对什么是“模型”的误解部分是由“MVC”的相同(过度)炒作造成的,而不太理解概念本身。有点像“ajax”是多么的空,甚至更简单,“web 2.0”。不管是好是坏,很多脚本孩子都已经加入了MVC的行列,而且由于简单的howto和示例场景只会告诉你把数据库代码放在“模型”中,所以滥用该层作为数据库抽象已经司空见惯。现在,你在互联网上看到了称之为“不守时”、“肮脏”、“黑客”的帖子,可以将任何业务逻辑放到模型中。这是错误的。误传。

    简单的例子是考虑外键:即使你只希望你的“模型”是一个 数据库 模型,如果你想成为“纯粹的”、“正确的”或者你拥有什么,你真的应该在其中强制执行参照完整性。由于多年来MySQL缺乏真正的外键支持,Web应用程序在成长过程中根本不需要担心引用完整性。我想这符合小鬼的生活方式。无论如何,为了使模型的这个简化视图能够保持外键的有效性,模型必须与其他人一起工作(或者,特别是,如果像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
  •  8
  •   MECU    16 年前

    这是可能的,但不理想,被认为是不好的,更多的是为了“快速修复”,而不是理想的或纯粹的实现。

    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
  •  6
  •   Dave Meybohm    14 年前

    正如Phil Sturgeon所说,您可以从模型中加载模型,但是如果您在模型构造函数中加载模型,则必须小心依赖关系:如果模型A使用模型B,而模型B使用模型A,则当您尝试加载其中一个或另一个模型时,您将进入一个无限循环。

        5
  •  1
  •   Zbyszek    15 年前

    在这种情况下,在代码点火器中,我更喜欢两种可能性之一:

    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);
        // ...
      }
      // ...
    }
    


    然后在其他方法之前使用这个setter来给出其他模型的一个实例,这样它就可以被方法使用。

    $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);
    



    我认为这是更为明确的可能性。
    使用哪种方法取决于访问其他模型需要多少方法。如果有一个或两个,最好将其作为方法参数。如果更多-我认为最好有一个类属性和setter。
    以优雅的方式,您可以根据某种条件给出一个或另一个模型——如果它们都部分地实现同一个接口,并返回相同类型的数据(这很少有用,但有时也有用)。

        6
  •  0
  •   KyleFarris    16 年前

    我认为访问模型并在需要时将库包含在模型中的编写库通常更好。

    例如,如果您需要检查某人是否有权执行某个CRUD操作,您可能希望包括正在使用的任何身份验证库(在大多数情况下,它可能是自动包含的)。您不一定想直接访问模型——它看起来很脏而且不合适。

    我认为首选的方法是在控制器中执行需要执行的操作,并将一个模型的方法(如果需要)的结果传递给另一个模型的方法。

    不管怎样,我不明白为什么不能将一个模型包含到另一个模型中。不过,我认为你不能用你正在展示的语法来完成。你得用另一种复杂的方式来做。在任何情况下,在我看来,把一个模型直接包含到另一个模型中是不好的做法。

        7
  •  0
  •   phirschybar    13 年前

    在CI2.0中,您可以直接从另一个模型调用一个模型。

        8
  •  -1
  •   Lakin Mohapatra    8 年前

    最好创建一个助手函数,而不是从另一个模型调用该函数,这样一次可以在两个模型中使用该函数,代码可以重用。