【问题标题】:Ruby on Rails - Why can't I use ActiveRecord::Base methods? Where to use?Ruby on Rails - 为什么我不能使用 ActiveRecord::Base 方法?在哪里使用?
【发布时间】:2015-02-27 16:31:36
【问题描述】:

我一直在尝试在我的应用程序中使用 ActiveRecord::Base 方法,例如 .each 和 .collect,但我不断收到未定义的方法错误!也许我对 Ruby 的了解不够深入。好像我不能在我的控制器、方法或视图中使用这些方法?

例如,下面的代码会给我一个未定义的方法'collect':

@articles = Article.collect{|x| x.publisher == 'Bloomberg'}

另外一个例子也会报错:

array = []
@articles = Article.each do |x|
   if x.publisher == 'Bloomberg'
      array << x
   end
end

我无法在我的控制器、模型或视图中使用这些方法。我可以在哪里使用它们?谁能告诉我我的基本 Ruby/Rails 代码是否错误?

我正在使用 Rails 4.20 和 Ruby 2.1.5p273

【问题讨论】:

  • 我认为(需要检查)您需要使用Article.all.each

标签: ruby-on-rails ruby-on-rails-4 rails-activerecord each collect


【解决方案1】:

.each.collect 是在 Ruby 中的 Enumerable mixin 中定义的集合方法,而不是在 ActiveRecord::Base 中定义的方法。

为了调用.each.collect,您需要一个响应这些方法调用的集合对象。所以使用:

@articles = Article.all.collect{|x| x.publisher == 'Bloomberg'}

和,

array = []
@articles = Article.all.each do |x|
   if x.publisher == 'Bloomberg'
      array << x
   end
end

要评论您可以在哪里使用它们,您可以在模型或控制器中使用它们,而不是在视图中使用它们。我建议将此代码放置在您的文章模型中的类方法甚至范围中。示例:

# app/models/article.rb

# Class method example:
# Usage: Article.by_publisher('Bloomberg')
def self.by_publisher(publisher_name)
  where(publisher: publisher_name)
end

# Scope example
# Usage: Article.by_publisher('Bloomberg')
scope :by_publisher, ->(publisher_name) { where(publisher: publisher_name) }

然后在您的控制器或视图中,您将使用eachcollect,类似于以下块:

Article.by_publisher('Bloomberg').each do |article|
  # article.title
end

【讨论】:

  • 哇!这很有帮助。我相信其他菜鸟也会有同样的问题,所以代表我们所有人,谢谢大家的帮助! :)
  • hmm... .all 似乎也是不允许的。它会产生同样的错误吗?
【解决方案2】:

方法 collect 并且每个方法都在 Enumerable 上定义。您需要先获取一系列文章才能使用它们。只需调用 Article 即可获得 Article 模型类,您需要使用 Article.all。

@articles = Article.all.collect{|x| x.publisher == 'Bloomberg'}

但是您可能希望在数据库级别执行此操作。将所有文章加载到内存中并过滤掉它们并不是一个好主意,您的数据库可以更快地为您完成此操作。试试下面的代码。

@articles = Article.where(publisher: 'Bloomberg')

【讨论】:

  • 注意!感谢您的提示,我肯定有一些 .where 有用的地方:)
  • 就在 Enumerable mixin 上!
【解决方案3】:

您可能应该使用范围。这是一个很好的起点:http://guides.rubyonrails.org/active_record_querying.html#scopes

如果您不想这样做,那么您可以在控制器中执行以下操作:

@articles = Article.where(publisher: 'Bloomberg')

【讨论】:

  • 太棒了!我希望我能给你们所有人打勾,谢谢你的帮助! :)
猜你喜欢
  • 2016-09-18
  • 1970-01-01
  • 2014-07-25
  • 2011-04-16
  • 2015-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多