繁体   English   中英

Rails模型的to_s方法

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM