在Rails中,有没有一种方法可以指定您想要的attr_accessor的类型,并使用内置的Rails验证来验证它?

发布于 2024-10-28 02:58:46 字数 754 浏览 1 评论 0原文

我一直找不到一个好的方法来做到这一点,所以我想我会问。

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

Category.new(params[:category])

Rails 知道name 是一个字符串,category_id 是一个整数。

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

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

attr_accessor :some_number_variable
attr_accessor :some_date

是否有一种内置方法可以告诉 Rails“当我进入类别时,我希望您将前者转换为整数,将后者转换为日期。 new(params[:category])" 只要 params[:category][:some_number_variable]params[:category][:some_date] 是提交给控制器的部分数据(我意识到,考虑到有多种日期格式,日期示例可能有点棘手)。

I've never been able to find a nice way to do this, so I thought I'd ask.

For example, in an ActiveRecord model, database backed attributes are automatically type-converted to the appropriate database-backed types. If I have a Category model, and it has a couple of attributes, say name and category_id, if I go like this:

Category.new(params[:category])

Rails knows that name is a String and category_id is an Integer.

Let's say I have several transient/synthetic attributes that I want to validate, and they have specific types. I want to submit them from a form, and I'd like them to be automatically converted to either a String or an Integer or a Date (for example) based on how they're defined.

If I was to declare something in a Rails model like:

attr_accessor :some_number_variable
attr_accessor :some_date

Is there a built-in way to tell Rails "I'd like you to cast the former to an Integer and the latter to a Date, when I go Category.new(params[:category])" so long as params[:category][:some_number_variable] and params[:category][:some_date] are part of the data submitted to the controller (I realize the Date example might be a bit trickier given the many date formats out there).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

倦话 2024-11-04 02:58:46

从 Rails 5 开始,您可以使用 Attribute API ,例如this:

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

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

As of Rails 5, there is the Attribute API which you can use like this:

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

You can set defaults, and define your own types, among other nice things. Then you can validate these attributes (virtual or not) like any other DB backed one.

漫雪独思 2024-11-04 02:58:46

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,我相信这是可能的。

attr_accesor just creates reader/writer methods, and it comes from Ruby, not Rails. The Rails method that I believe often gets confused is attr_accessible which serves a different purpose. If you want to cast when the attribute is read, you can just override the reader.

attr_accessor :some_number_variable

def some_number_variable
  @some_number_variable.to_i
end

This will at least give you the writer for free. This is the best solution I know for what (I think) you are describing.

EDIT: As far as validation is concerned, I believe that if you are using Rails 3, it will be much easier for you to perform validation on these sort of attributes (I haven't done it so I can't say for sure). Now that validations aren't tied directly into ActiveRecord, I'd believe it possible.

那支青花 2024-11-04 02:58:46

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

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

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

I assume by "transient/synthetic" attribute you mean a virtual attribute?

If so, there is no built in Rails function that will do this that I can think of offhand, but one solution would be to just write a module for those attributes and include it in the model. Or if it had to be dynamic, you could call the attribute something like :some_variable_integer and then handle those dynamic attributes with method_missing, read the method name, and convert it to the type required.

In my opinion, those are a little messy, so validations in the model are really your best bet if what you're looking to do can support them.

久伴你 2024-11-04 02:58:46

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

Neither of the replies quite answer the question. I believe the correct answer to the questions is simply "No". The replies both address potential workarounds to the fact that the answer to the question is "No", and both are valid comments / ideas.

最好是你 2024-11-04 02:58:46

使用 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

use 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
简单气质女生网名 2024-11-04 02:58:46

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

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

参考:Rails ActiveRecord::MultiparameterAssignmentErrors

Add the following to your model:

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

reference: Rails ActiveRecord::MultiparameterAssignmentErrors

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文