美文网首页
(2)delegate原理与使用

(2)delegate原理与使用

作者: suhuanzhen | 来源:发表于2016-11-27 17:52 被阅读0次

    我们在新的分支上进行开发

    git checkout -b second/delegate
    
    git branch
      master
    * second/delegate
    
    rails g migration CreateProductInfoes
    
    商品补充信息表 product_infoes
    image.png image.png

    添加模型文件


    image.png

    填充数据


    image.png

    案例应用delegate

    为products表添加外键

    rails g migration AddProductInfoIdToProducts
    
    image.png
    rake  db:migrate
    

    填充数据


    image.png

    使用场景

    最常见的是我们通过product.product_info.Weight访问关联表的数据。如果我们想要product.Weight的方式来得到关联表的数据就可以使用delegate方法。然后我们product.Weight访问的时候,它就会自动去查找关联的product_info.Weight。

    添加belongs_to :product_info(必须添加,下面会讲原因)和delegate


    image.png

    添加路由


    image.png

    添加动作

    #second
    def delegate  
      @products = Product.limit(3)
    end
    

    添加视图文件


    image.png

    页面效果


    image.png
    控制台输出
    image.png
    delegate原理

    上面我们访问Weight的原理其实很简单,就是我们自定义一个方法返回关联表的Weight字段。我们以PreSaleAmount为例子,product.PreSaleAmount其实不是访问product模型的PreSaleAmount字段,而是调用模型的PreSaleAmount方法

    因为PreSaleAmount方法中需要访问关联表,所以我们必须添加模型关联belongs_to :product_info,这也就是我们前面说的delegate必须确保有belongs_to的理由

    image.png image.png image.png

    如上products表中ProductInfoID为info22的记录访问不到关联的数据表数据,所以返回PreSaleAmount为0

    delegate的原理就是如上定义方法返回关联表的字段,product.Weight实际上是调用product模型的Weight方法。只不过这是rails提供的接口,我们就不需要为每个字段定义这样的方法。

    我们自定义的PreSaleAmount处理了关联表数据不存在的特殊情况,但是delegate则没有处理这类异常,如下ProductInfoID为info22的记录访问不到关联的数据表数据,所以访问Weight字段值报错


    image.png
    image.png

    既然delegate接口没有处理异常,那么我们可以在视图文件中添加判断语句


    image.png
    image.png

    delegate方法优先级高于模型字段,如果我们在delegate中添加了Price,那么我们product.Price时,就不会访问products表的Price字段,而是访问product_infoes表的Price字段。

    使用includes解决n+1问题

    控制台输出:


    image.png

    我们可以使用includes

    def delegate  
      @products = Product.includes(:product_info).limit(3)
    end
    

    使用includes之后控制台输出信息


    image.png

    提交到git仓库

    git add .
    git commit -m "delegate原理与使用"
    git push -u https://github.com/xiaohuacc/active_record.git second/delegate
    

    然后我们在git仓库就可以看到新提交的分支了


    image.png

    然后我们返回主分支,把这次分支的修改合并到主分支

    git checkout master
    git merge second/delegate
    
    Updating bf2bd5a..6dd2565
    Fast-forward
     .idea/workspace.xml                                          | 179 ++++++++++++++++++++++++++++----------
     app/controllers/products_controller.rb                       |   5 ++
     app/models/product.rb                                        |  10 +++
     app/models/product_info.rb                                   |   3 +
     app/views/products/delegate.html.erb                         |   5 ++
     config/routes.rb                                             |   6 +-
     db/migrate/20161127081543_create_product_infoes.rb           |  11 +++
     db/migrate/20161127095910_add_product_info_id_to_products.rb |   5 ++
     db/schema.rb                                                 |  24 +++--
     9 files changed, 193 insertions(+), 55 deletions(-)
     create mode 100644 app/models/product_info.rb
     create mode 100644 app/views/products/delegate.html.erb
     create mode 100644 db/migrate/20161127081543_create_product_infoes.rb
     create mode 100644 db/migrate/20161127095910_add_product_info_id_to_products.rb
    

    相关文章

      网友评论

          本文标题:(2)delegate原理与使用

          本文链接:https://www.haomeiwen.com/subject/rxlnpttx.html