何时在 Rails 3 中使用虚拟属性或在哈希中传递数据

发布于 2024-11-16 22:25:16 字数 815 浏览 7 评论 0原文

在我的应用程序中,我有一个 Widget 模型,一个 Feature 模型,通过 WidgetFeature 表与 has_many through 关联。

根据要求,当我发送 WidgetFeature 对象时,对于给定的关联功能,我还应该将 feature_name 附加到该对象。
有两种方法可以实现:

  1. 在发送对象时,执行以下操作:
widget_feature_object[:feature_name] = feature_name_value

然后我可以在我的控制器或视图中通过 widget_feature_object[:feature_name] 访问它,因为对象具有(键,值)对,所以我也可以添加另一个。

2.将 feature_name 设为 WidgetFeature 模型中的虚拟属性,然后为其创建getter 和 setter 方法

据我所知,当您想要创建与模型中实际存在的字段不同的不同视图时,您应该使用虚拟属性(例如,全名 = 名字 + 姓氏)。
同样的事情也适合这里吗?

另外,Rails 是否会对对象进行一些缓存,当您使用虚拟属性时(而不是当我使用第一种方法时),这可能会很有用?

每种方法的优缺点是什么,哪种方法最适合我的要求? 多谢。

In my application, I have a Widget model, a Feature model with a has_many through association by WidgetFeature table.

As per the requirements, when I am sending a WidgetFeature object, I should append the feature_name to it as well, for the given feature associated.
There are two ways of going at it:

  1. While sending the object, do this:
widget_feature_object[:feature_name] = feature_name_value

and then I can access it in my controller or view, by widget_feature_object[:feature_name] because an object has (key, value) pairs, so I can add another too.

2 . Make feature_name a Virtual Attribute in WidgetFeature model, and then create getter and setter methods for it.

From what I know, that you should use virtual attributes when you want to create a different view different from the fields actually present in the model (e.g Full name = First name + Last name).
Does the same thing fits in here too?

Also, does Rails do some caching on objects, that might get in useful when you use virtual attributes and not when I use the first approach?

What are the pros and cons of each approach and which one suits the best as per my requirements?
Thanks a lot.

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

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

发布评论

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

评论(3

冷︶言冷语的世界 2024-11-23 22:25:17

我建议另一种方法:使用 delegate (文档)。

WidgetFeature 中我会写:

class WidgetFeature

  belongs_to :feature

  delegate :name, :to => :feature, :prefix => true
end

然后你就可以写

f = WidgetFeature.first

f.feature_name #will return f.feature.name

希望这有帮助。

I would propose an alternative approach: use delegate (documentation).

In the WidgetFeature I would write:

class WidgetFeature

  belongs_to :feature

  delegate :name, :to => :feature, :prefix => true
end

then you will be able to write

f = WidgetFeature.first

f.feature_name #will return f.feature.name

Hope this helps.

〆一缕阳光ご 2024-11-23 22:25:17

当您希望能够设置方法时,请使用 attr_accessor。否则就使用通用函数。

如果你想缓存,请查看 memoization

Use attr_accessor when you want to be able to set a method. Otherwise just use general functions.

If you want to cache, look into memoization

晒暮凉 2024-11-23 22:25:17

我不确定为什么您坚持使用 [] 表示法来访问您的属性,但要遵循的一种途径是:

def [](attr)
  if attr == :feature
    feature    # Return the associated feature object
  else
    super      # Call ActiveRecord::Base#[]
  end
end

当然,您可以通过一些元编程来自动检测有效关联来完善它。

我个人不太喜欢这种方式的猴子补丁,但由于 [] 是一个简单的方法,你可能是安全的。好处是,这允许您使用 widget_feature[:feature][:name] 甚至 widget_feature[:feature][:name]=

您可以通过调用 widget_feature.feature 获得所有 ActiveRecord 功能。

I'm not sure why you insist on using the [] notation to access your attributes, but one path to follow is this one:

def [](attr)
  if attr == :feature
    feature    # Return the associated feature object
  else
    super      # Call ActiveRecord::Base#[]
  end
end

Of course you could nice it up with some metaprogramming to automatically detect valid associations.

I personally don't really like monkeypatching in this fashion, but since [] is a simple method you're probably safe. The upside is that this allows you to widget_feature[:feature][:name] and even widget_feature[:feature][:name]=

You get all the ActiveRecord functionality that you would with calling widget_feature.feature.

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