[英]Rails model to_s method
在我的Rails应用程序中,在“产品”和“类别”之间定义了一种关系。 每个产品可以具有不同的类别。
我以这种方式显示产品的类别:
<p>
<strong>Categories:</strong>
<%= @product.categories.join(", ") unless @product.categories.nil? %>
</p>
和我的Category
模型:
class Category < ActiveRecord::Base
def to_s
@name
end
end
但是,在显示页面中,类别显示如下:
Categories: #<Category:0x007f2bf515b148>, #<Category:0x007f2bf515aef0>, #<Category:0x007f2bf515ac98>
为什么to_s
方法不起作用? 我该如何解决?
@product.categories
的结果是ActiveRecord::Relation
,而不是数组。 因此, join
方法是在关系类内部实现的方法,而不是Array#join
。
您应该将列表隐式转换为数组
<%= @product.categories.to_a.join(", ") unless @product.categories.nil? %>
否则您应该更加注意自己的实际需求,避免加载整个对象并获得更有效的结果。
<%= @product.categories.pluck(:name).join(", ") unless @product.categories.nil? %>
值得一提的是您可以使用to_sentence
方法。
<%= @product.categories.pluck(:name).to_sentence unless @product.categories.nil? %>
此外, .nil?
检查是完全没有用的,因为@product.categories
是一个关系,永远不会为零。
而且,如果您确实想编写更好的代码,则可以避免在视图中实现逻辑,而要依赖于助手和模型。
class Product
def category_names
categories.pluck(:name)
end
end
module ProductsHelper
def product_categories_list(product)
product.category_names.to_sentence
end
end
<%= product_categories_list(@product) %>
尝试做如下定义方法:
class Category < ActiveRecord::Base
def to_s
self.name
end
end
要访问属性(如果它是表中的一列),则不应使用@attr_name,因为它们不会存储为实例变量。
尝试仅重新定义您的to_s
方法,如下所示:
class Category < ActiveRecord::Base
def to_s
name
end
end
这种行为的方式非常有趣:
class Role < ActiveRecord::Base
def to_s
nil
end
end
然后
"#{Role.first}"
=> "#<Role:0x00000007a39f88>"
但:
Role.first.to_s
=> nil
我已经进行了一项实验来找出问题所在,建议您查看结果。
这是pry
REPL的输出。 它不是一个Rails模型,但指出了这个问题。
我做了什么:我定义了一个新类,并指示它在所有不存在的方法上输出名称。 这是确定类上隐式调用的便捷技巧。
[1] pry(main)> class Hi
[1] pry(main)* def method_missing(sym)
[1] pry(main)* puts sym
[1] pry(main)* end
[1] pry(main)* end
=> :method_missing
[2] pry(main)> a = [Hi.new, Hi.new]
=> [#<Hi:0x0000000405b028>, #<Hi:0x0000000405afd8>]
[3] pry(main)> a.join
to_str
to_str
to_ary
to_str
to_ary
=> "#<Hi:0x0000000405b028>#<Hi:0x0000000405afd8>"
不是to_s
。 显然是to_str
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.