Rails 6.1.0发布了

2020-12-10 04:33:29

确保MemoryStore默认情况下禁用压缩。将MemoryStore的行为还原为其先前的rails 5.1行为。

在负持续时间上调用iso8601会在单个数字上保留负号,而不是在它前面加上。

此项更改是必需的,因此我们可以与PostgreSQL进行互操作,而PostgreSQL希望每个组件都带有负号。

仍然保留了与其他iso8601解析器的兼容性,这些解析器支持前置负片以及每个组件的负片。

配置cache_store =:mem_cache_store#现在等同于config。 cache_store =:mem_cache_store,ENV [" MEMCACHE_SERVERS" ] || " localhost:11211" #代替config。 cache_store =:mem_cache_store," localhost:11211" #忽略ENV [" MEMCACHE_SERVERS"]

ActiveSupport :: Subscriber#attach_to现在接受一个initialize_all:参数。设置为true时,它允许订阅者接收该订阅者祖先类中定义的方法的事件。

类ActionControllerSubscriber< ActiveSupport ::订户attach_to:action_controller def start_processing(event)info"按#{event处理。有效载荷[:controller]}##{事件。有效载荷[:action]}为#{格式}" end def redirect_to(event)info {"已重定向到#{event。有效负载[:location]}" } end##我们将ActionControllerSubscriber从:action_controller命名空间中分离出来,以便我们的CustomActionControllerSubscriber#可以为命名空间ActionControllerSubscriber中的某些事件提供自己的检测手段。 detach_from(:action_controller)类CustomActionControllerSubscriber< ActionControllerSubscriber attach_to:action_controller,Inherit_all:true def start_processing(event)info"对start_processing事件的自定义响应"结束#=> CustomActionControllerSubscriber将处理" start_processing.action_controller"的事件通知#使用其自己的#start_processing实现,同时保留ActionControllerSubscriber的工具#的redirect_to.action_controller"通知结束

解决了ActiveSupport :: Cache :: MemCacheStore中的问题,该问题导致重复压缩,并导致不遵守提供的compression_threshold。

已记录require_dependency在:zeitwerk模式下已作废。目前尚未弃用该方法,但建议应用程序不要使用它。

在:zeitwerk模式下,语义与Ruby相匹配,并且您不必在装入顺序上采取防御措施。通常只引用类和模块。如果常量名称是动态的,则在需要时驼峰化并常量化。

+ 1.second现在与+ 1.second相同,可以防止出现错误的格式更改导致代码行为发生更改的错误。

Time.at(1498099140).in_time_zone.inspect#=> "星期四,2017年6月22日02:39:00 UTC +00:00" Time.at(1498099140,123456780,:nsec).in_time_zone.inspect#=> "星期四,2017年6月22日02:39:00 UTC +00:00" Time.at(1498099140 + Rational(" 1/3"))。in_time_zone.inspect#=> "星期四,2017年6月22日02:39:00 UTC +00:00"

Time.at(1498099140).in_time_zone.inspect#=> "星期四,2017年6月22日02:39:00.000000000 UTC +00:00" Time.at(1498099140,123456780,:nsec).in_time_zone.inspect#=> "星期四,2017年6月22日02:39:00.123456780 UTC +00:00" Time.at(1498099140 + Rational(" 1/3"))。in_time_zone.inspect#=> "星期四,2017年6月22日02:39:00.333333333 UTC +00:00"

新的Rails 6.1应用程序默认情况下启用了该功能,现有应用程序可以通过config / initializers / new_framework_defaults_6_1.rb中的配置进行升级

ActiveSupport :: Callbacks#halted_callback_hook现在将被暂停的回调名称作为第二个参数。此更改将使您能够区分哪些回调使链中断并采取相应措施。

班级< ApplicationRecord before_save {throw(:abort)} before_create {throw(:abort)} def halted_callback_hook(filter,callback_name)Rails。记录器。 info(" Book不能为#{callback_name} d")结束Book。创建#=> "无法创建图书"书。保存#=> "无法保存图书"结束

Imposter模块扩展ActiveSupport :: Concern#与`included`相同,除了仅在前置时运行。预先做endendclass人在事前Imposterend

类方法是在基类之前添加的,有关的也进行了更新:有关:Imposter,前置的:true。

使用Range#include弃用吗?检查日期时间范围内值是否包含的方法。建议使用Range#cover?方法而不是Range#include?检查日期时间范围内是否包含值。

number_to_currency(1234567890.50,precision:0,round_mode::half_down)#=> " $ 1,234,567,890" number_to_percentage(302.24398923423,精度:5,round_mode::down)#=> " 302.24398%" number_to_rounded(389.32314,精度:0,round_mode::ceil)#=> " 390" number_to_human_size(483989,精度:2,round_mode::up)#=> " 480 KB" number_to_human(489939,精度:2,round_mode::floor)#=> " 48万" 485000。 to_s(:human,precision:2,round_mode::half_even)#=> " 48万"

当ActiveSupport :: Duration实例转换为iso8601持续时间字符串时,如果星期与日期部分混合,则星期部分将转换为天。这样可使解析器和序列化器保持在同一页面上。

duration = ActiveSupport :: Duration。 build(1000000)#1周4天13小时46分钟40.0秒duration_iso =持续时间。 iso8601#P11DT13H46M40S ActiveSupport ::持续时间。 parse(duration_iso)#11天13小时46分钟40秒duration = ActiveSupport :: Duration。 build(604800)#1周duration_iso =持续时间。 iso8601#P1W ActiveSupport ::持续时间。解析(duration_iso)#1周

解决了#37012中描述的错误行为集,其中在比较由String实例构建的持续时间时,ActiveSupport :: Duration比较会令人困惑地失败或返回意外结果。

small_duration_from_string = ActiveSupport :: Duration.build(' 9')large_duration_from_string = ActiveSupport :: Duration.build(' 100000000000000')small_duration_from_int = ActiveSupport :: Duration.build(9)large_duration_from_string> small_duration_from_string#=> falsesmall_duration_from_string == small_duration_from_int#=> falsesmall_duration_from_int< large_duration_from_string#=> ArgumentError(ActiveSupport :: Duration :: Scalar与ActiveSupport :: Duration失败的比较)large_duration_from_string> small_duration_from_int#=> ArgumentError(字符串与ActiveSupport :: Duration的比较失败)

当您想删除#blank时,添加compact_blank? Enumerable的值(在Hash,Array,ActionController :: Parameters上也为compact_blank!)。

在ActiveSupport :: Logger#local_level =中使用Fiber.current .__ id__,以使日志级别对于Thread之外的Ruby Fiber都是本地的。

logger = ActiveSupport :: Logger.new(STDOUT)logger.level = 1puts"主要是调试吗? #{logger.debug?}" Fiber.new {logger.local_level = 0将"线程调试? #{logger.debug?}"}。resumeputs"主要是调试吗? #{logger.debug?}"

允许解密/验证消息时使用的on_rotation proc在构造函数级别传递。

如果委派给的对象为nil,则proxy_missing_to将引发委派错误。现在,添加了allow_nil选项,以使用户可以指定他们希望在这种情况下返回nil。

如果截断的字符串太短而无法截断,则truncate将返回原始字符串;如果截断的长度足够长,则截断将返回冻结的字符串。现在,无论如何,截断将始终返回未冻结的字符串。此行为与gsub和strip一致。

这在human_attribute_name方法依赖于其他属性的情况下很有用。验证中的类的值,以得出属性名称应为什么。

尝试在冻结的对象上写入数据库不支持的属性时,引发FrozenError:

动物类包括ActiveModel :: Attributes属性:ageendanimal = Animal.newanimal.freezeanimal.age = 25#=> FrozenError,无法修改被冻结的Animal"

现在,ActiveModel的错误集合是这些错误对象的数组,而不是消息/详细信息哈希。

对于每个错误对象,其message和full_message方法均用于生成错误消息。它的details方法将返回错误的额外参数,该参数在原始details哈希中找到。

所做的更改会尽力保持向后兼容性,但是不会涵盖某些极端情况,例如error#first将返回ActiveModel :: Error并处理error.messages和errors.details散列直接无效。展望未来,请将这些直接操作转换为使用提供的API方法。

在下一个主要版本中,不推荐使用的方法及其计划的未来行为更改的列表为:

errors#每个带有键的值,两个参数的块将停止工作,而错误的单个参数的块将返回Error对象。

该API允许应用程序立即连接到多个数据库,而无需切换所有数据库或实现深度嵌套的堆栈。

Dogs.first#从动物副本中读取Dinner.first#从膳食副本中读取Person.first#从主要作者端读取

ActiveRecord :: Base.connected_to_many([AnimalsRecord,MealsRecord],角色:: reading)做Dog.first#从动物副本中读取Dinner.first#从膳食副本中读取Person.first#从主要作者端读取

如果使用strict_loading,某些应用程序可能不希望在生产中引发错误。这将允许应用程序设置严格的负载以记录生产环境,同时仍在开发和测试环境中进行记录。

通过使用引用名称而不是type和id列名称来优化多态引用的索引名称的长度。

因为添加多列索引时的默认行为是使用索引名称中的所有列名称,所以这经常会导致多态引用的索引名称过长,如果超出数据库限制,迁移将失败。

此更改通过使用引用名称(例如, index_my_table_on_my_reference。

MySQL:唯一性验证器现在遵守默认的数据库排序规则,默认情况下不再强制进行区分大小写的比较。

Relation.create不再将范围泄漏到初始化块和回调中的类级查询方法。

User.where.not(name:" Jon&#34 ;,角色:" admin")#SELECT * FROM users where where name!=' Jon' AND角色!=' admin'

User.where.not(name:" Jon&#34 ;,角色:" admin")#SELECT * FROM FROM WHERE NOT(name ==' Jon' AND role = =' admin')

允许用户保持沉默,无法推断您是否正在使用多个数据库..."使用config.active_record.suppress_multiple_database_warning的消息。

此更改使connected_to可以为单个抽象类而不是全局所有类切换角色和/或分片。想要使用新功能的应用程序需要在其应用程序配置中将config.active_record.legacy_connection_handling设置为false。

给定一个应用程序,我们有一个从ApplicationRecord继承的User模型和一个从AnimalsRecord继承的Dog模型。 AnimalsRecord和ApplicationRecord具有写入和读取连接以及分片默认值(一个和两个)。

ActiveRecord :: Base。 connected_to(role::reading)做User。 first#从默认副本Dog读取。首先#从默认副本AnimalsRecord读取。 connected_to(角色::写作,碎片::一个)做用户。 first#从默认副本Dog读取。 first#从分片读取一个主要最终用户。 first#从默认副本Dog读取。 first#从默认副本ApplicationRecord读取。 connected_to(角色::writing,shard::two)做User。首先#从分片中读取两个主要的Dog。第一个#从默认副本结束读取

类别< ApplicationRecord validates_uniqueness_of:title,条件:-> (文章){published_at =文章。 published_at,其中(published_at:published_at.beginning_of_year..published_at.end_of_year)}}结束

BatchEnumerator#update_all和BatchEnumerator#delete_all现在返回受影响的行总数,就像它们的非批处理对应行一样。

从数据库加载记录并在保存时序列化为ISO 8601格式的持续时间字符串时,添加对PostgreSQL间隔数据类型的支持,并转换为ActiveSupport :: Duration。添加支持以在迁移中定义一列并在架构转储中获取它。支持可选的列精度。

要在6.1中使用它,您需要将下一个字符串放置到模型文件中:

create_table:events | t | t.string:name t.interval:durationendclass事件< ApplicationRecord属性:duration,:intervalendEvent.create!(名称:' Rock Fest&#39 ;,持续时间:2.days)Event.last.duration#=> 2 daysEvent.last.duration.iso8601#=> " P2D" Event.new(持续时间:' P1DT12H3S')。duration#=> 1天12小时3秒Event.new(duration:' 1 day')#未知值将被忽略,并将NULL写入数据库

添加SKIP_TEST_DATABASE环境变量,以在调用rails db:create和rails db:drop时禁止修改测试数据库。

确保只能从ActiveRecord :: Base或抽象类中调用connect_to。这样可以防止应用程序打开重复或过多的连接。

现在,所有执行的连接适配器在遇到连接错误时都会引发ActiveRecord :: ConnectionNotFounded而不是ActiveRecord :: StatementInvalid。

如果多个数据库应用程序提供了名为primary的配置,则将其视为默认配置。在没有主条目的应用程序中,默认数据库配置将是环境的第一个配置。

类注释< ActiveRecord ::基本枚举标签:[:default,:child] has_many:children,class_name:" Comment" ,foreign_key::parent_id end#...来自评论者LEFT OUTER JOIN评论子孙ON ... WHERE children.label = 1评论。包括(:children)。其中(" children.label&#34 ;:" child")

在Rails 6.1之前,store_full_sti_class类属性仅支持STI类型的存储已解调的类名。

废弃rails db:structure:{load,dump}任务,并扩展rails db:schema:{load,dump}任务以:ruby或:sql格式使用,具体取决于config.active_record.schema_format配置值。

post =发布。选择(" UPPER(title)AS title")。第一帖。标题#=> "欢迎访问博客"发布。正文#=> ActiveModel :: MissingAttributeError#Rails 6.0(忽略“ select”值)post = Post。选择(" UPPER(title)AS title")。 eager_load(:comments)。第一帖。标题#=> "欢迎访问网络日志"发布。正文#=> "真是美好的一天" #Rails 6.1(尊重“ select”值)post = Post。选择(" UPPER(title)AS title")。 eager_load(:comments)。第一帖。标题#=> "欢迎访问博客"发布。正文#=> ActiveModel :: MissingAttributeError

类Post< ActiveRecord ::基本属性:write_at,默认值:-> { 时间 。现在。 utc} end#Rails 6.0发布。 type_for_attribute(:write_at)#=> #< Type :: Value ...精度:nil,...> #Rails 6.1发布。 type_for_attribute(:write_at)#=> #< Type :: DateTime ...精度:6,...>

添加了设置ActiveRecord :: Base.immutable_strings_by_default,该设置允许您指定应冻结所有字符串列,除非另行指定。对于通常不会更改Active Record对象的字符串属性的应用程序,这将减少内存压力。

david_and_mary =作者。其中(id:[大卫,玛丽])mary_and_bob =作者。其中(id:[mary,bob])david_and_mary。合并(mary_and_bob)#=> [mary,bob] david_and_mary。和(mary_and_bob)#=> [mary] david_and_mary。或(mary_and_bob)#=> [大卫,玛丽,鲍勃]

同一列上的合并条件不再保留这两个条件,并且将在Rails 6.2中被后者条件一致地替换。要迁移到Rails 6.2的行为,请使用Relation.merge(其他位置,为true)。

#Rails 6.1(IN子句由合并方相等条件代替)Author。其中(id:[david。id,mary。id])。合并(作者。其中(id:bob))#=> [bob]#Rails 6.1(两个冲突条件都存在,已弃用)Author。其中(id:david。id .. mary。id)。合并(作者。其中(id:bob))#=> []可以迁移到Rails 6.2的行为Author的#Rails 6.1。其中(id:david。id .. mary。id)。 merge(作者。where(id:bob),rewhere:true)#=> [bob]#Rails 6.2(与IN子句的行为相同,始终合并合并边条件)Author。其中(id:[david。id,mary。id])。合并(作者。其中(id:bob))#=> [bob]作者。其中(id:david。id .. mary。id)。合并(作者。其中(id:bob))#=> [鲍勃]

当分配值仅因大小写而变化时,请勿将Postgresql MAC地址和UUID属性标记为已更改。

当将ActiveRecord :: Persistence.insert_all和ActiveRecord :: Persistence.upsert_all的:unique_by选项与表达式索引的名称一起使用时,会引发错误。围绕:unique_by的格式化行为添加保护措施可以纠正此问题。

create_table:books,id :: integer,force:true做| t | 。列:name,:string t。索引"下部(名称)" ,独特:真正的结局。 insert_all [{名称:" MyTest" }],unique_by::index_books_on_lower_name

添加ActiveRecord :: Base.strict_loading_by_default和ActiveRecord :: Base.strict_loading_by_default =默认情况下为模型启用/禁用strict_loading模式。子类可以继承配置的值,但是它们可以覆盖该值,并且不会影响父类。

类开发人员< ApplicationRecord自身。 strict_loading_by_default = true has_many:项目结束dev =开发人员。第一开发。项目。首先#=> ActiveRecord :: StrictLoadingViolationError异常:开发人员被标记为strict_loading,并且无法延迟加载Project。

添加了委托类型,以替代单表继承来表示类层次结构。有关完整说明,请参见ActiveRecord :: DelegatedType。

帐户=帐户。 group(:firm_id)#重复的组字段,已弃用。 帐户。 合并(帐户。其中。不(credit_limit:nil))。 sum(:credit_limit)#=> {#[1,1] => 50,#[2,2] => 60#}#使用`uniq!(:group)`去重复组字段。 帐户。 合并(帐户。其中。不(credit_limit:nil))。 uniq! (:group)。 sum(:credit_limit)#=> {#1 => 50,#2 => 60#} 帐户=帐户。 其中(id:[1,2])。 注释(" david和mary")#不重复的注释。 帐户。 merge(accounts。rewhere(id:3))#选择帐户。*从帐户所在的account.id = 3 / * david和mary * / / * david和mary * /#使用`uniq!(:annotate)`进行重复数据删除 注释。 帐户。 合并(帐户。 ......