(2)delegate原理与使用

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

git checkout -b second/delegate

git branch
  master
* second/delegate
rails g migration CreateProductInfoes
商品补充信息表 product_infoes
(2)delegate原理与使用_第1张图片
image.png
(2)delegate原理与使用_第2张图片
image.png

添加模型文件


image.png

填充数据


(2)delegate原理与使用_第3张图片
image.png

案例应用delegate

为products表添加外键

rails g migration AddProductInfoIdToProducts
(2)delegate原理与使用_第4张图片
image.png
rake  db:migrate

填充数据


(2)delegate原理与使用_第5张图片
image.png

使用场景

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

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


(2)delegate原理与使用_第6张图片
image.png

添加路由


(2)delegate原理与使用_第7张图片
image.png

添加动作

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

添加视图文件


(2)delegate原理与使用_第8张图片
image.png

页面效果


(2)delegate原理与使用_第9张图片
image.png

控制台输出
(2)delegate原理与使用_第10张图片
image.png
delegate原理

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

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

(2)delegate原理与使用_第11张图片
image.png
(2)delegate原理与使用_第12张图片
image.png
(2)delegate原理与使用_第13张图片
image.png

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

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

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


(2)delegate原理与使用_第14张图片
image.png

(2)delegate原理与使用_第15张图片
image.png

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


(2)delegate原理与使用_第16张图片
image.png

(2)delegate原理与使用_第17张图片
image.png

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

使用includes解决n+1问题

控制台输出:


(2)delegate原理与使用_第18张图片
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仓库就可以看到新提交的分支了


(2)delegate原理与使用_第19张图片
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原理与使用)