在Rails中重写getter/setter,同时保留Model.new({attrib:'blah'})格式 [英] Overriding getter/setter in Rails whilst preserving Model.new({attrib: 'blah'}) format

查看:91
本文介绍了在Rails中重写getter/setter,同时保留Model.new({attrib:'blah'})格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我在模型中重写了一个getter和setter方法,那么在控制器中为该属性创建默认初始值的最佳方法是什么?

If I override a getter and setter in my model, what's the best way to create default initial values for that attribute in my controller?

例如,当我在控制器中创建模型的新实例以包含一些初始值时,表单中的预填充值将显示设置器而非获取器的输出.

For instance, when I create a new instance of the model in the controller to include some initial values, the pre-populated values in the form show the output from the setter rather than the getter.

这应该怎么做?

示例

class Something < ActiveModel:Base
  # override getter
  def attr_a
    self[:attr_a] * 5 
  end
  # override setter
  def attr_a=
    self[:attr_a] = attr_a / 5 # i.e. 10 / 5 = 2
  end
end

class SomethingController < ActiveController
  def new
    @something = Something.new({attr_a: 10})
  end
end

# index.html.erb
<% form_for @something do |f| %>
  <% f.text_field :attr_a %>
  <% f.submit 'Save' %>
<% end %>

在此示例中,表单中的text_field填充为2而不是10.

In this example, the text_field in the form is populated with 2 rather than 10.

通过显示2作为对象实例化的一部分正在调用设置,我可以理解为什么有意义,但是我是不是在以错误的方式获得想要的结果呢?

I can see why it makes sense to by showing 2 as the setting's being called as part of the object instantiation, but am I going about things the wrong way to get the result I want?

从本质上讲,数据需要以与应用程序逻辑中使用的方式以及用户应看到的方式不同的方式存储在数据库中.我想让它尽可能地无缝.

Essentially, data needs to be stored in the database in a different way to how it's used in application logic and what the user should see. I want to make that as seamless as possible.

推荐答案

我不会使用相同的属性名称.如果数据库中的值与对象返回的值不同,则这会造成混淆并且容易出错.某人不知道所发生的转换将生成有问题的代码,例如:

I would not use the same attribute name. If the value in the DB is different than what your object returns then this is confusing and error prone. Somebody who is unaware of the conversion that takes place will build buggy code like:

Something.where('attr_a < 10')

如果确实需要,则可以使用read_attribute(:attr_a)write_attribute(:attr_a, value)从对象内部读取/写入属性值.

If you reallyreally have to, then you can read/write the attribute value with read_attribute(:attr_a) and write_attribute(:attr_a, value) from inside the object.

但是我会做这样的事情:假设您要存储商品的价格 Product以美分为整数. (忽略特殊情况,例如nil或form提交时出现字符串和浮点除法问题,舍入等):

But I'd do something like this: Assuming that you want to store the price of a Product in cents as integer. (Ignoring special cases like nil or form submits with strings and floating point division problems, rounding and so on) :

class Product < ActiveRecord::Base
  def price
    price_in_cents / 100.0
  end 
  def price=(value)
    self.price_in_cents = value * 100
  end
end

这篇关于在Rails中重写getter/setter,同时保留Model.new({attrib:'blah'})格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆