has_many has_one belongs_to都有设置dependent属性
has_many的文档里写的dependent是设置为:destroy将调用关联对象destroy方法,如果设置为:delete_all将调用class.delete_all而不调用destroy方法,:nullify就是直接将外键设为null.
has_one的文档里写的dependent是设置为:destroy将调用关联对象destroy方法,如果设置为:delete将调用class.delete而不调用destroy方法,:nullify就是直接将外键设为null.
belongs_to的文档里写的dependent是设置为:destroy将调用关联对象destroy方法,如果设置为:delete将deleted而不调用destroy方法.
继续查源代码了解清楚一点:
1) has_many的源代码:
def has_many(association_id, options = {}, &extension)
reflection = create_has_many_reflection(association_id, options, &extension)
configure_dependency_for_has_many(reflection)
...
end
# delete children, otherwise foreign key is set to NULL.
def configure_dependency_for_has_many(reflection)
if reflection.options.include?(:dependent)
# Add polymorphic type if the :as option is present
dependent_conditions = []
dependent_conditions << "#{reflection.primary_key_name} = \#{record.quoted_id}"
dependent_conditions << "#{reflection.options[:as]}_type = '#{base_class.name}'" if reflection.options[:as]
dependent_conditions << sanitize_sql(reflection.options[:conditions]) if reflection.options[:conditions]
dependent_conditions = dependent_conditions.collect {|where| "(#{where})" }.join(" AND ")
case reflection.options[:dependent]
when :destroy # 一个个用destroy删除
method_name = "has_many_dependent_destroy_for_#{reflection.name}".to_sym
define_method(method_name) do
send("#{reflection.name}").each { |o| o.destroy }
end
before_destroy method_name
when :delete_all # 用delete_all指令删除,hook proc到before_destroy
module_eval "before_destroy { |record| #{reflection.class_name}.delete_all(%(#{dependent_conditions})) }"
when :nullify # 用update_all指令更新为null,hook proc到before_destroy
module_eval "before_destroy { |record| #{reflection.class_name}.update_all(%(#{reflection.primary_key_name} = NULL), %(#{dependent_conditions})) }"
else
raise ArgumentError, "The :dependent option expects either :destroy, :delete_all, or :nullify (#{reflection.options[:dependent].inspect})"
end
end
end
如果只是简单的关联,has_many的delete_all方法会比destroy效率高不少,destroy是一个n+1查询。
实践证明其实对于大表的删除,最好不使用dependent属性,性能问题迟早会找上来
2) has_one的源代码:
def has_one(association_id, options = {})
...
configure_dependency_for_has_one(reflection)
end
def configure_dependency_for_has_one(reflection)
if reflection.options.include?(:dependent)
case reflection.options[:dependent]
when :destroy # 创建destroy关联方法,hook到before_destroy
method_name = "has_one_dependent_destroy_for_#{reflection.name}".to_sym
define_method(method_name) do
association = send("#{reflection.name}")
association.destroy unless association.nil?
end
before_destroy method_name
when :delete # 创建delete关联方法,调用类的delete(id)方法,hook到before_destroy
method_name = "has_one_dependent_delete_for_#{reflection.name}".to_sym
define_method(method_name) do
association = send("#{reflection.name}")
association.class.delete(association.id) unless association.nil?
end
before_destroy method_name
when :nullify # 调用record.update(attr,nil),hook到before_destroy
method_name = "has_one_dependent_nullify_for_#{reflection.name}".to_sym
define_method(method_name) do
association = send("#{reflection.name}")
association.update_attribute("#{reflection.primary_key_name}", nil) unless association.nil?
end
before_destroy method_name
else
raise ArgumentError, "The :dependent option expects either :destroy, :delete or :nullify (#{reflection.options[:dependent].inspect})"
end
end
end
3) belongs_to相关源代码:
def belongs_to(association_id, options = {})
...
configure_dependency_for_belongs_to(reflection)
end
def configure_dependency_for_belongs_to(reflection)
if reflection.options.include?(:dependent)
case reflection.options[:dependent]
when :destroy # 直接调用destroy删除,hook到before_destroy
method_name = "belongs_to_dependent_destroy_for_#{reflection.name}".to_sym
define_method(method_name) do
association = send("#{reflection.name}")
association.destroy unless association.nil?
end
before_destroy method_name
when :delete #调用类方法的delete(id)删除,hook到before_destroy
method_name = "belongs_to_dependent_delete_for_#{reflection.name}".to_sym
define_method(method_name) do
association = send("#{reflection.name}")
association.class.delete(association.id) unless association.nil?
end
before_destroy method_name
else
raise ArgumentError, "The :dependent option expects either :destroy or :delete (#{reflection.options[:dependent].inspect})"
end
end
end
分享到:
相关推荐
rails-settings, 使用 Ruby on Rails 管理设置 Rails的设置 ruby gem,通过在单独的数据库表中将它们存储为序列化的哈希来处理。 包含命名空间和默认值。要求ruby 1.9.3或者更高版本Rails 3.1或者更高版本( 包括 ...
附上Jamis的rdoc模板文件,tar解压即可。 博文链接:https://lgn21st.iteye.com/blog/199681
标题中的“Rails的中文乱码问题”涉及到的是在使用Ruby on Rails框架开发Web应用时,遇到的中文字符编码不正确的问题。Rails是一个基于Ruby语言的开源Web开发框架,它遵循MVC(Model-View-Controller)架构模式。在...
Rails 实践 设置 分叉并克隆存储库 安装 gems - bundle 设置数据库 - rake db:create db:migrate db:seed 启动服务器 - rails s 您可以使用以下命令运行规范: rspec 注意:由rake db:seed填充的现有用户的电子...
bower-rails, 在 Rails 上,为 Bower 设置类似 DSL + rake任务 rails Bower 对 Rails 项目的支持。 依赖文件是 Rails root 目录中的bower.json,如果使用 DSL,则为 Bowerfile 。 查看最新变更和发布的变更日志文件...
chef-rails, 厨房设置一个可以与 Nginx 和 Rails 一起滚动的Ubuntu服务器 主厨 rails安装一个准备为 Ruby on Rails 栈准备的Ubuntu服务器:NginxPostgreSQLRedisMemcached带RVM的rubyPhusion乘客独立要求Ubuntu ...
#### 七、练习作业1-建立Group-CRUD与RESTful - **CRUD操作**: - Create (创建): 创建新的Group对象。 - Read (读取): 显示Group的信息。 - Update (更新): 修改Group的信息。 - Delete (删除): 删除Group。 - ...
此外,书中还介绍了一些Rails中的高级概念,如Strong Parameters(强参数),它在Rails 4.0版本中引入,用于解决之前版本中的参数篡改问题,从而帮助开发者安全地处理外部提交的数据。 通过一系列的教学内容,包括...
1. **Rails框架基础**: Rails的核心理念是DRY(Don't Repeat Yourself),它鼓励开发者编写简洁、可复用的代码。框架提供了丰富的内置功能,如路由、ORM(对象关系映射)、数据库迁移和强大的脚手架工具,帮助快速...
1. **约定优于配置**(Convention Over Configuration):Rails通过默认的约定减少开发者需要明确配置的细节,如数据库表名与类名的对应关系。 2. **Active Record**:这是Rails中的ORM(对象关系映射)库,它允许...
知识点1:Ruby 安装 * 下载 Ruby One-Click Installer 版本 * 安装 Ruby * 检查 Ruby 版本 知识点2:Rails 安装 * 下载 Rails 2.0.2 版本 * 安装 Rails * 检查 Rails 版本 知识点3:Mongrel 安装 * 下载 ...
例如,要在Rails应用中创建一个新的资源,如博客文章,你需要在models目录下创建一个名为`post.rb`的文件,定义Post类,并设置属性如标题和内容。在controllers目录下创建`posts_controller.rb`,定义控制器方法,如...
从给定的文件信息来看,我们正在探讨的是一本关于Ruby on Rails的书籍,书名为《Simply Rails2》,作者是Patrick Lenz。本书旨在为初学者提供深入理解Ruby on Rails框架的指南,从基础概念到高级主题均有涵盖,是...
然而,有时在尝试连接Rails应用到MySQL数据库时,可能会遇到一些问题。本篇文章将深入探讨这些常见问题及其解决方案。 首先,Rails与MySQL的连接问题可能源于配置不正确。在`config/database.yml`文件中,你需要...
1. **优化性能**:Rails应用在处理大量请求时可能会面临性能挑战。书中会介绍如何通过缓存(如Action Cache和Page Cache)、数据库查询优化、资产管道优化等手段提升应用性能。 2. **复杂的路由**:Rails的路由系统...
Rails 3.1 和 Cucumber-Rails 1.2.0 是两个在Web开发领域非常重要的工具,尤其对于Ruby on Rails框架的测试和自动化流程。本文将深入探讨这两个组件,以及它们如何协同工作来增强软件开发的效率和质量。 首先,...
Rails Recipes是一本针对Ruby on Rails框架的实用书籍,它收集了一系列高效解决问题的技巧和方法,也被称为“Rails开发者的宝典”。作者们通过分享自己的经验和见解,为Rails程序员提供了一本既有实际操作指导又有...
1. **activesupport-2.1.0.gem**:ActiveSupport是Rails的一个重要库,提供了许多实用的工具和方法,如时间区处理、字符串格式化、数组和哈希操作等。它也包含了一些核心的Ruby扩展,帮助开发者编写更简洁、更具表达...