(02)种子数据,给关联起别名,class_name和sourc

2016-11-30  本文已影响0人  suhuanzhen

我们切换到新的分支进行开发

git checkout -b class_name_and_source

补充,前面多对多本质也是两个1对多。而1对多关系只需要属于多的那张表添加外键即可,如用户和微博是1对多,微博属于多的那方,所以只需要posts表添加UserID这个外键,users表不用修改表结构。而前面多对多中多的是中间表那方,所以中间表保存两个外键,其他表的表结构不用修改。

一言概之:

class_name只会出现在下面两种情况(第二种情况还必须用source):
1、给1对多起别名
2、给多对多起别名

source只会出现在下面两种情况(第二种情况加不加source都可以):
1、has_many+through+给多对多关联起别名(:class_name)
2、has_many+through

class_name

class_name给1对多关系起别名

创建模型文件,我们这回就不考虑前后端分离自定义表名的情况,所以就不写迁移文件,直接使用生成模型的命名(会生成一些我们这里不用的测试文件)

rails g model User name:string age:integer
rails g model Post title:string content:string UserID:integer
rake  db:migrate
rake db:seed

然后我们在数据库就可以看到生成的种子数据了



上面就已经完成了模型关联,上面就是最常见的方式。我们可以使用user.posts获取该用户下的所有微博。


如果我们希望user.weibos也能获取到该用户下的所有微博呢(也就是给关联起别名)?
这就是class_name的使用场景。



使用了别名class_name之后,就不能继续使用user.posts这样的方式了

我们还可以把post.user修改为post.yonghu的方式



起别名只是名称修改,单复数还是和原来默认的一样,has_many后面是别名复数,belongs_to后面是别名单数

给多对多起别名,class_name+source

给多对多起别名,就是给中间表的两个1对多起别名。因为中间表保存两个表的外键,class_name指明了要关联的模型名,source则指明用中间表的哪个外键去关联到该模型,不然会报错。
用法如下:


如果不加source会报错如下:

product.lou_cengs
ActiveRecord::HasManyThroughSourceAssociationNotFoundError:
Could not find the source association(s) "lou_ceng" or :lou_cengs in model ActivityFloorProduct. 
Try 'has_many :lou_cengs, :through => :activity_floor_products, :source => <name>'. 
Is it one of activity_floor or product?

给另外一个模型起别名:



错误示例

既然多对多关联通过中间表起别名有两个表可以指定关联,那么需要使用source指明关联哪张表-----source的值应该就是class_name模型对应的表名单数。

分析如下:在楼层模型里面,source正确的情况下是:product,用中间表的ProductID去关联class_name对应的products表,所以第一条sql是正确的,ON `products`.`ID` = `activity_floor_products`.`ProductID`
而source: :activity_floor则是
ON `products`.`ID` = `activity_floor_products`.`ActivityFloorID`

正确:
SELECT `products`.* FROM `products` INNER JOIN `activity_floor_products` ON `products`.`ID` = `activity_floor_products`.`ProductID` WHERE `activity_floor_products`.`ActivityFloorID` = 'floor01'
错误:
SELECT `products`.* FROM `products` INNER JOIN `activity_floor_products` ON `products`.`ID` = `activity_floor_products`.`ActivityFloorID` WHERE `activity_floor_products`.`ActivityFloorID` = 'floor01'

提交到git仓库

进入项目根目录

.../active_record_second#  git init
Initialized empty Git repository in /home/**********/active_record_second/.git/
git add -A
git commit -m "(02)种子数据,给关联起别名,class_name和source"

提交

git push -u https://github.com/xiaohuacc/active_record_second.git class_name_and_source
上一篇下一篇

猜你喜欢

热点阅读