使用模型关联可能很困难。

在构建我的模拟Central Perk和Ruby on Rails应用程序时。 has_manybelongs_to关系是有意义的,但是通过关系的多对多has_many through关系是很奇怪的地方。

在构建应用程序时遇到了几个问题,这就是我解决问题的方式。

模型行为

对于我的项目,我计划使用三种模型:用户(咖啡师),订单和菜单项(产品)。 一个用户可能有很多订单。 属于用户的订单可能有许多菜单项

使用这些模型,我希望能够以编程方式执行以下操作:

  • 创建一个新订单并自动将其与用户关联。 shannon.orders.create
  • 能够查看属于用户的所有订单。 shannon.orders
  • 按特定顺序查看所有MenuItems(产品)。 order.menu_items

设置好模型后,一切似乎都可以正常运行,直到order.menu_items为止。 当前,具有menu_items属性的Order只能有一个值。 含义,每个订单一个 MenuItem。 您是否可以想象是否必须重新排队并为要在咖啡店购买的每种商品重新订购?

罗斯和瑞秋看上去很困惑

这是一个has many through关系的地方。

多对多

如果每个订单我想要多个MenuItem,则order.menu_items的结果必须是一个数组。 这是四个OrderItem模型出现的地方。

OrderItem充当OrderItem表,并带有OrderMenuItems模型的外键。 在此示例中,考虑到每个OrderItem记录都有一个事务实例,一次代表一个Order和一个MenuItem

订单本质上是具有相同order_id的所有OrderItem记录的集合。 我离弄清楚我需要什么又走了一步。

但?

首先,使用OrderItem模型是有意义的。

直到没有。

我需要调用order.order_items.menu_items来查看该订单中的所有商品吗? 我的应用程序也有一个User模型。 当模型超过三个时,如何通过关系构建has_many?

Pheobe到处喊着“我该怎么办?”

实际上,has_many through仅适用于三种模型。 但是,通过其他关联,它扩展了那些模型的功能。 如果我想知道一个特定用户创建的一阶user.orders.first.menu_items.count我可以这样称呼: user.orders.first.menu_items.count

在视觉上,我认为这四个模型之间的关系如下所示:

通过用户,订单(包含OrderItems)和菜单项之间的关系可视化has_many

这很有意义!

我不需要直接引用OrderItems 。 ActiveRecord对我有用。 由于Order有许多OrderItems ,因此引用Order将使我可以直接访问MenuItems

我的最终模型现在看起来像这样:

class User < ApplicationRecordhas_secure_passwordhas_many :orders
endclass Order < ApplicationRecordbelongs_to :userhas_many :order_itemshas_many :menu_items , through: :order_items
endclass OrderItem < ApplicationRecordbelongs_to :orderbelongs_to :menu_item
endclass MenuItem < ApplicationRecordhas_many :order_itemshas_many :orders , through: :order_items
end

参数

完成关联后,我需要一个表单来创建Order对象。 一开始,一切似乎都在进行。 但是在仔细查看控制台之后,我意识到事务正在回滚并且订单没有保存到数据库中。

我注意到:menu_items_id键已在我的强参数中列出,但是我遇到了“ :menu_items_ids不允许错误”。

为了尝试解决此问题,我在控制台中进行了工作,一点一点地进行了测试,直到可以查明卡住的位置。 在控制台中,我可以成功执行以下操作。

  • 创建订单。 order = Order.create(user_id: 1, name_for_pickup: "Rachel", menu_item_ids: [1,2,3])
  • 查看order上menu_items的值order.menu_items // [1,2,3]
  • 将商品添加到订单中order.menu_items << item
  • 保存订单order.save

然后打我。

Rails正确地不允许menu_item_ids参数。 我以为我需要创建一个订单。 相反,我需要创建一个订单, find the menu items by id (menu_items_id, which was the unpermitted param) and shovel them into the array

我从这里更新了我的创建订单方法:

def create@order = Order.create(order_params)if @order.saveredirect_to order_path(@order)elserender :newend
end

对此

def create@order = Order.create(order_params)items_to_add = params[ :order ][ :menu_item_ids ]items_to_add.each do |item_id|if item_id != ""item_id = item_id.to_iitem_to_add = MenuItem.find_by_id(item_id)@order.menu_items << item_to_addendendif @order.saveredirect_to order_path(@order)elserender :newendend

而且有效!

钱德跳上咖啡桌,做快乐的舞蹈

得到教训

总之,如果遇到对象关系问题,请尝试以下操作:

验证参数正确

错别字会立即导致对象创建失败。 诸如menu_item_idmenu_item_ids类的复数形式也值得关注。 所有参数都是字符串 ,如果期望整数或布尔值,则可能会导致下游影响。

所有模型属性均以强参数列出

强大的参数有助于防止用户通过表单将有害数据注入到您的数据库中。 如果强参数只能在User模型中提交:name:email:password ,则如果:not_a_hacker的属性在您的参数之内,则事务将失败(并且不会写入数据库,是的!)。

使用.create! 测试时

create! 将提供更多信息,说明哪些验证可能导致错误。 例如,在我的应用程序中, Order必须具有关联的User (barista)user_id。 在控制台中运行Order.create()不会告诉我太多,但是运行Order.create!()会打印出类似User User must exist的错误。

将`.valid?`附加到对象

对象可能正在更新,但是它是否正确保存到数据库中? 例如,如果order = Order.create() (一个空对象,因为没有:user_id ,它将不生效),添加.valid? 将返回false。

摘要

模型关联可能很困难且令人沮丧,但并非不可能。 通过一些仔细的调试,您可以立即成为模型关联的大师。

资源资源

  • 什么是Rails参数以及如何正确使用它们
  • 活动记录协会

安妮·斯普拉特 Annie Spratt) Unsplash 拍摄的 照片

先前发布在https://shannoncrabill.com/blog/ruby-on-rails-debugging-model-associations/

From: https://hackernoon.com/debugging-has_many-through-relationships-in-ruby-on-rails-a65s366p

通过Ruby on Rails中的关系调试Has_Many相关推荐

  1. 在Ruby on Rails中对nil v。空v。空白的简要解释

    我发现自己一再寻找nil?差异的明确定义nil? , blank? , empty? 在Ruby on Rails中. 这是我最接近的: blank? 对象是false,空或空白字符串. 例如, &q ...

  2. 如何在Ruby on Rails中获得当前的绝对URL?

    如何在Ruby on Rails视图中获取当前的绝对URL ? request.request_uri仅返回相对URL. #1楼 url_for(params) 您可以轻松添加一些新参数: url_f ...

  3. ruby on rails 中使用boot strap(先存起来,还没试过)

    1.首先安装  gem 'twitter-bootstrap-rails' ,运行bundle install 2.初始化 rails generate bootstrap:install less  ...

  4. 新手安装ruby on rails(ror)的成功必备手册

    2019独角兽企业重金招聘Python工程师标准>>> 如何快速正确的安装 Ruby, Rails 运行环境 每一位使用windows系统来进行ROR开发项目的都是这个世界上折翼的天 ...

  5. Ruby on Rails 终极部署方案 nginx+mina+puma

    搭建工具介绍 Ruby on Rails作为一款十分优秀的web开发框架,在当前web领域中慢慢占据了越来越重要,秉承rails快速开发的特点,很多快速部署rails的方案也越来越多.这篇文章中所选的 ...

  6. 如何从Hash中删除一个键并获取Ruby / Rails中的剩余哈希?

    要向Hash添加新对,我会: {:a => 1, :b => 2}.merge!({:c => 3}) #=> {:a => 1, :b => 2, :c => ...

  7. 如何在Ruby on Rails迁移中重命名数据库列?

    我错误地将列命名为hased_password而不是hashed_password . 如何使用迁移重命名此列来更新数据库架构? #1楼 如果当前数据对您不重要,您可以使用以下方法删除原始迁移: ra ...

  8. [转载] Ruby、Rails、Agile的启示

    转自:http://vipnews.csdn.net/newscontent.aspx?pointid=2008_03_03_170600555 文/杨祥吉 本文作者以使用Ruby和Rails进行创业 ...

  9. Ruby on Rails 的秘笈是什么?

    Ruby on Rails 的秘笈是什么? 我们能从 Rails 框架学到的经验 文档选项 将此页作为电子邮件发送 级别: 初级 Bruce Tate ([email]bruce.tate@j2lif ...

  10. Ruby on Rails的核心特性是什么?

    Ruby on Rails好像一直处于争论的风口浪尖.大多数争论的核心是其所宣称的令人惊异的生产力.作者Bruce Tate已经开始理解Rails并不是一个更好的工具,而是一个不同类型的工具.本文研究 ...

最新文章

  1. 现实工程中常用到的C语言函数总结(不断更新)
  2. LeetCode—210. 课程表 II
  3. Mockito –带有注释和静态方法的额外接口
  4. 基于java的数据结构学习——泛型动态数组的封装
  5. Spring Boot 1.5.x新特性:动态修改日志级别
  6. 一文读懂云计算和PAYG“现付现用”模型
  7. 问题 G: 编写函数:数组的排序 (Append Code)
  8. HDU2567 寻梦【输入输出流+水题】
  9. 在 Hibernate 中出现 database product name cannot be null 时怎么解决?
  10. matlab中输出汉字的函数,matlab中的输出显示函数
  11. 怪物猎人世界pc服务器在哪个文件夹,关于PC怪物猎人世界拆包文件的一些问题...
  12. 软件介绍——SyncToy 微软官方文件同步工具
  13. 开发APP需要准备哪些工作
  14. 科技的性感:三星冰洗如何演绎时尚生活?
  15. Verilog结构描述
  16. 萌新谈相机与IMU的标定(转载)
  17. zlib 1.2.9 not found
  18. 如何读懂EDIFACT报文?
  19. 速领电商:怎么制作视频短片
  20. 搜索引擎的索引和搜索

热门文章

  1. 最小二乘法求回归直线方程的详细推导过程
  2. 从原理到实战,一份详实的 Scrapy 爬虫教程
  3. greenplum(gp)postgre清理pg_xlog释放空间
  4. 2021年深度学习哪些方向比较新颖,处于上升期或者朝阳阶段,比较有研究潜力?...
  5. 数学连乘和累加运算符号_数学运算符号
  6. 谷歌表格快捷键_所有最好的Google表格键盘快捷键
  7. Acute Angle Cloud与Achain达成战略合作,共促区块链系统发展
  8. 【升级到Java 17】switch 表达式
  9. GOOGLE:单一模式背后
  10. 51定时器PWM调节