我从来没有找到一个很好的方法来做到这一点,所以我想我会问。
例如,在ActiveRecord模型中,数据库支持的属性会自动进行类型转换为适当的数据库支持类型。如果我有一个Category
模型,它有几个属性,比如name
和category_id
,如果我这样:
Category.new(params[:category])
Rails知道name
是一个字符串而category_id
是一个整数。
假设我有几个我要验证的瞬态/合成属性,并且它们具有特定类型。我想从表单中提交它们,我希望它们根据它们的定义自动转换为String或Integer或Date(例如)。
如果我要在Rails模型中声明一些内容,例如:
attr_accessor :some_number_variable
attr_accessor :some_date
是否有一种内置的方式告诉Rails“我希望你把前者转换为整数,后者转换为日期,当我去Category.new(params[:category])
”只要params[:category][:some_number_variable]
和params[:category][:some_date]
是提交给控制器的数据的一部分(我发现Date示例可能有点棘手,因为有很多日期格式)。
这两个回复都没有完全回答这个问题。我相信这些问题的正确答案就是“不”。回复都解决了潜在的解决方法,即问题的答案是“否”,两者都是有效的评论/想法。
从Rails 5开始,有Attribute API可以像这样使用:
class SomeModel < ActiveRecord::Base
attribute :a_checkbox_name, :boolean, default: false
end
您可以设置默认值,并定义自己的类型,以及其他好东西。然后,您可以像任何其他DB支持的属性一样验证这些属性(虚拟或非虚拟)。
attr_accesor
只是创建读者/作者方法,它来自Ruby,而不是Rails。我认为经常会混淆的Rails方法是为attr_accessible
服务的a different purpose。如果要在读取属性时进行强制转换,则可以覆盖读取器。
attr_accessor :some_number_variable
def some_number_variable
@some_number_variable.to_i
end
这至少可以免费给你作家。这是我所知道的(我认为)你所描述的最佳解决方案。
编辑:就验证而言,我相信如果你使用Rails 3,你将更容易对这些属性进行验证(我没有这样做,所以我不能肯定地说) 。既然验证没有直接绑定到ActiveRecord,我相信它是可能的。
我假设“transient / synthetic”属性是指虚拟属性?
如果是这样,没有内置的Rails函数可以做到这一点,我可以随意考虑,但一种解决方案是只为这些属性编写一个模块并将其包含在模型中。或者如果它必须是动态的,您可以调用属性类似于:some_variable_integer,然后使用method_missing处理这些动态属性,读取方法名称,并将其转换为所需类型。
在我看来,这些都有点混乱,所以如果您想要做的事情可以支持它们,那么模型中的验证确实是您最好的选择。
使用before_create ..
class Category
attr_accessor :some_number_variable, :some_date
before_create :validate
private
def validate
return unless !!params[:category]
#do variable casting here
end
end
将以下内容添加到您的模型中:
columns_hash["birth_date"] = ActiveRecord::ConnectionAdapters::Column.new("birth_date", nil, "date")