在我们的rails 3.2.12应用中,我们希望override method
为instance
并使其返回为空。理想情况下,我们可以为应用中的每个generic overriding method
定义一个model
。
例如,@project
是Project
模型的实例,phone
是列名。在方法覆盖之后,我们希望@project.phone
在运行时返回空,而不是列的值。如果应用中有另一个模型customer
,我们可以@customer.name
并且假设@customer
是instance
的{{1}},则会收到nil。
我们认为customer
和singleton class
可能对此有所帮助。但我们不太明白他们将如何工作。有人能解释一下这个问题吗?谢谢你的帮助。
答案 0 :(得分:3)
忽略这一切,额外的评论使这一点毫无价值。
不要覆盖实例方法,为什么不只是有一个实例变量,就像方法的开关一样。
class Project < ActiveRecord::Base
def phone
if @do_not_call
nil
else
super
end
end
def do_not_call
@do_not_call = true
end
def do_call
@do_not_call = false
end
end
你需要像CanCan这样的东西
https://github.com/ryanb/cancan
使用can can可以设置用户的能力,并执行以下操作。
class Project < ActiveRecord::Base
def phone
if current_user can? :phone, self
super
else
nil
end
end
end
答案 1 :(得分:1)
覆盖对象(实例)方法的一种方法如下:
@project = Project.find(params[:id])
#@project.phone contains the database value
def @project.phone
""
end
#@project.phone returns an empty string now
答案 2 :(得分:1)
既然你说你只想在视图中这样做,那么我觉得视图助手值得考虑:
# view.html.haml
= value_for_view(:phone, @project)
# application_helper.rb
def value_for_view(attribute, object)
if overide_attributes_in_view? && object.respond_to?("#{attribute}_for_view")
object.send("#{attribute}_for_view")
else
object.send(attribute)
end
end
# application.rb
def overide_attributes_in_view?
#do your stuff here to determine whether the original values should be shown or the 'overloads'
end
# project.rb
def phone_for_view
nil # just add methods called "attribute_for_view" for whatever attributes you want to whatever models you want to have the attributes 'overloaded' (it's not really overloading, but it serves the purpose you describe)
end
或类似地......你可以修补AR :: Base以获得'value_for_view'方法,因此视图看起来更像是这样:
# view.html.haml
= @project.value_for_view(:phone)
# monkey_patch_file.rb
def value_for_view(attribute)
if respond_to?("#{attribute}_for_view")
send("#{attribute}_for_view")
else
send(attribute)
end
end
如果您坚持只能调用@project.phone并获取一个或其他值,那么您需要传递@project一个标志,告诉它为您进行计算,因为Rovermicroer的答案显示(但是,正如我评论的那样,我不确定'超级'会起作用,但原则是正确的。)