Rails 4通用alias_attribute实现问题求助
解决通用
alias_attribute的驼峰转蛇形问题 我来帮你搞定这个通用别名的问题!你的思路是对的,但代码里有两个关键问题导致没达到预期效果,咱们一步步修正:
原代码的问题分析
你写的这段代码:
self.attribute_names.each { |attr| alias_attribute attr.split(/(?=[A-Z])/).join("_").downcase.to_sym, :attr }
有两个核心问题:
- 第二个参数用了硬编码的
:attr符号,而不是循环变量attr对应的属性符号,导致所有别名都指向一个不存在的:attr属性 - 手动用正则拆分驼峰的逻辑不够健壮,比如遇到连续大写字母的情况可能处理得不够好(比如
IDColumn会拆成i_d_column,而我们期望是id_column)
正确的实现方案(Rails环境)
Rails自带了underscore方法,可以完美处理驼峰转蛇形的需求,我们可以利用它来简化代码,同时修正参数错误:
# 在你的模型类中添加这段代码 self.attribute_names.each do |db_attr| # 将驼峰式数据库字段转成蛇形别名 alias_attr = db_attr.underscore.to_sym # 仅当别名和原属性名不同时才创建别名,避免重复定义报错 alias_attribute alias_attr, db_attr.to_sym unless alias_attr == db_attr.to_sym end
举个例子:
- 数据库字段
GenericDataBaseColumn会被转成别名generic_data_base_column - 如果字段已经是蛇形(比如
user_name),则跳过创建别名,避免冗余
纯Ruby环境的兼容方案(无Rails)
如果你的项目不是Rails项目,没有自带的underscore方法,可以自己实现一个类似的转换方法:
class YourModel # 自定义驼峰转蛇形方法 def self.underscore(str) str.gsub(/([a-z\d])([A-Z])/, '\1_\2') .gsub(/([A-Z])([A-Z][a-z])/, '\1_\2') .downcase end # 批量创建别名 self.attribute_names.each do |db_attr| alias_attr = underscore(db_attr).to_sym alias_attribute alias_attr, db_attr.to_sym unless alias_attr == db_attr.to_sym end end
这个自定义方法会处理大多数常见的驼峰场景,比如:
GenericDataBaseColumn→generic_data_base_columnIDColumn→id_columnUserAPI→user_api
内容的提问来源于stack exchange,提问作者Carlos J García
相关产品推荐
相关产品推荐

