我目前有一个模型Attend会有一个状态列,而这个状态列只有几个值。 STATUS_OPTIONS = {:yes,:no,:maybe}
1)我不确定在用户插入Attend之前我如何验证这一点?基本上是java中的枚举,但我怎么能在rails中做到这一点?
答案 0 :(得分:64)
现在Rails 4.1
包含枚举,您可以执行以下操作:
class Attend < ActiveRecord::Base
enum size: [:yes, :no, :maybe]
# also can use the %i() syntax for an array of symbols:
# %i(yes no maybe)
validates :size, inclusion: { in: sizes.keys }
end
然后为每个检查器方法提供一个范围(例如:Attend.yes
,Attend.no
,Attend.maybe
,以查看是否设置了某个状态(即:#yes?
,#no?
,#maybe?
),以及属性设定方法(即:#yes!
,#no!
,#maybe!
)。
答案 1 :(得分:36)
创建所需选项的全局可访问数组,然后验证状态列的值:
class Attend < ActiveRecord::Base
STATUS_OPTIONS = %w(yes no maybe)
validates :status, :inclusion => {:in => STATUS_OPTIONS}
end
然后,您可以通过Attend::STATUS_OPTIONS
答案 2 :(得分:11)
这是我在Rails 4项目中实现的方式。
class Attend < ActiveRecord::Base
enum size: [:yes, :no, :maybe]
validates :size, inclusion: { in: Attend.sizes.keys }
end
Attend.sizes为您提供映射。
Attend.sizes # {"yes" => 0, "no" => 1, "maybe" => 2}
答案 3 :(得分:5)
您可以使用字符串列作为状态,然后使用:inclusion
option for validates
以确保只获得您期望的内容:
class Attend < ActiveRecord::Base
validates :size, :inclusion => { :in => %w{yes no maybe} }
#...
end
答案 4 :(得分:3)
我们开始做的是在数组中定义枚举项,然后使用该数组指定枚举,验证和使用应用程序中的值。
STATUS_OPTIONS = [:yes, :no, :maybe]
enum status_option: STATUS_OPTIONS
validates :status_option, inclusion: { in: STATUS_OPTIONS.map {|t| t.to_s } }
这样您也可以稍后使用STATUS_OPTIONS,就像创建下拉列表一样。如果您想将值公开给用户,您可以像这样映射:
STATUS_OPTIONS.map {|s| s.to_s.titleize }
答案 5 :(得分:1)
对于ActiveModels中的枚举,您可以使用此gem Enumerize
答案 6 :(得分:0)
经过一番观察后,我找不到模型中的单线来帮助它发生。到目前为止,Rails提供了枚举,但不是验证无效值的综合方法。
因此,我选择了一个复合解决方案:在设置strong_params
之前在控制器中添加验证,然后检查模型。
因此,在模型中,我将创建一个属性和一个自定义验证:
<强> attend.rb 强>
enum :status => { your set of values }
attr_accessor :invalid_status
validate :valid_status
#...
private
def valid_status
if self.invalid_status == true
errors.add(:status, "is not valid")
end
end
另外,我将检查无效输入的参数并将结果(如有必要)发送到模型,因此会将错误添加到对象中,从而使其无效
<强> attends_controller.rb 强>
private
def attend_params
#modify strong_params to include the additional check
if params[:attend][:status].in?(Attend.statuses.keys << nil) # to also allow nil input
# Leave this as it was before the check
params.require(:attend).permit(....)
else
params[:attend][:invalid_status] = true
# remove the 'status' attribute to avoid the exception and
# inject the attribute to the params to force invalid instance
params.require(:attend).permit(...., :invalid_status)
end
end
答案 7 :(得分:0)
要定义动态行为,可以使用In [32]: tst = pd.DataFrame({"label" : [1, 2, None, 3, None], "value" : ["A", "B", None, "C", None]})
Out[39]:
label value
0 1.0 A
1 2.0 B
2 NaN None
3 3.0 C
4 NaN None
In [51]: type(tst.value[2])
Out[51]: NoneType
In [52]: type(tst.label[2])
Out[52]: numpy.float64
表示法:
in: :method_name