6

我从来没有找到一个很好的方法来做到这一点,所以我想我会问。

例如,在 ActiveRecord 模型中,数据库支持的属性会自动类型转换为适当的数据库支持类型。如果我有一个Category模型,并且它有几个属性,比如说nameand category_id,如果我这样做:

Category.new(params[:category])

Rails 知道这name是一个字符串并且category_id是一个整数。

假设我有几个要验证的瞬态/综合属性,它们有特定的类型。我想从表单提交它们,并且我希望它们根据它们的定义方式自动转换为字符串、整数或日期(例如)。

如果我要在 Rails 模型中声明某些内容,例如:

attr_accessor :some_number_variable
attr_accessor :some_date

是否有一种内置方式告诉 Rails “我希望你将前者转换为整数,而将后者转换为日期,当我去时Category.new(params[:category])”,只要params[:category][:some_number_variable]并且params[:category][:some_date]是提交给控制器的数据的一部分(我意识到鉴于那里有许多日期格式,日期示例可能有点棘手)。

4

6 回答 6

7

从 Rails 5 开始,您可以像这样使用Attribute API :

class SomeModel < ActiveRecord::Base
  attribute :a_checkbox_name, :boolean, default: false
end

您可以设置默认值,并定义自己的类型,以及其他不错的功能。然后,您可以像任何其他数据库支持的属性一样验证这些属性(虚拟或非虚拟属性)。

于 2018-09-08T05:51:27.270 回答
1

attr_accesor只是创建读取器/写入器方法,它来自Ruby,而不是 Rails。我认为经常混淆的 Rails 方法是attr_accessible用于不同的目的。如果要在读取属性时进行强制转换,则可以覆盖读取器。

attr_accessor :some_number_variable

def some_number_variable
  @some_number_variable.to_i
end

这至少会给你免费的作家。对于您所描述的(我认为),这是我所知道的最佳解决方案。

编辑:就验证而言,我相信如果您使用的是 Rails 3,对这些属性执行验证会容易得多(我没有这样做,所以我不能肯定地说) . 现在验证没有直接绑定到 ActiveRecord,我相信这是可能的。

于 2011-03-28T18:34:57.423 回答
0

我假设“瞬态/合成”属性是指虚拟属性?

如果是这样,没有内置的 Rails 函数可以做到这一点,我可以临时想到,但一种解决方案是只为这些属性编写一个模块并将其包含在模型中。或者,如果它必须是动态的,您可以调用类似 :some_variable_integer 的属性,然后使用 method_missing 处理这些动态属性,读取方法名称,并将其转换为所需的类型。

在我看来,这些有点混乱,所以如果你想要做的事情可以支持它们,那么模型中的验证确实是你最好的选择。

于 2011-03-28T18:37:05.820 回答
0

这两个答复都没有完全回答这个问题。我相信这些问题的正确答案只是“不”。这些答复都针对问题的答案是“否”这一事实提出了潜在的解决方法,并且都是有效的评论/想法。

于 2011-03-31T00:12:23.577 回答
0

使用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
于 2012-01-08T04:30:17.397 回答
0

将以下内容添加到您的模型中:

columns_hash["birth_date"] = ActiveRecord::ConnectionAdapters::Column.new("birth_date", nil, "date")

参考:Rails ActiveRecord::MultiparameterAssignmentErrors

于 2012-12-30T21:41:29.047 回答