对关联和从控制台获取信息感到困惑
Confusion over assocation and getting info from console
对尝试从 Rails 控制台获取信息感到困惑
我有以下型号:Article
& Comment
。
对于 Article
,它是 has_many :comments
对于 Comment
,它是 belongs_to :article
让我们假设它们是关联的,并且是有效的。顺便说一下。
架构如下:
ActiveRecord::Schema.define(version: 20160312052519) do
create_table "articles", force: :cascade do |t|
t.string "title"
t.text "text"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "comments", force: :cascade do |t|
t.string "commenter"
t.text "body"
t.integer "article_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "comments", ["article_id"], name: "index_comments_on_article_id"
end
这些是路线:
resources :articles do
resources :comments
end
当我 运行 命令如下:
Article.first.comments
Comment.first.article
Comment.first.article.title
Comment.first.article.text
Comment.first.commenter
Comment.first.body
它们都有效。
但是当我尝试 运行 在 Articles
上进行反向操作时,例如:
Article.first.comments.commenter
Article.first.comments.body
Article.all.comments
它们不起作用。为什么不?
编辑
这是我在 运行 Article.first.comments.commenter
时得到的
Article.first.comments.commenter
Article Load (23.0ms) SELECT "articles".* FROM "articles" ORDER BY "articles"."id" ASC LIMIT 1
NoMethodError: Comment Load (0.4ms) SELECT "comments".* FROM "comments" WHERE "comments"."article_id" = ? [["article_id", 1]]
undefined method `commenter' for #<Comment::ActiveRecord_Associations_CollectionProxy:0x007fa32b7e3d00>
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activerecord-4.2.5/lib/active_record/relation/delegation.rb:136:in `method_missing'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activerecord-4.2.5/lib/active_record/relation/delegation.rb:99:in `method_missing'
from (irb):127
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/railties-4.2.5/lib/rails/commands/console.rb:110:in `start'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/railties-4.2.5/lib/rails/commands/console.rb:9:in `start'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/railties-4.2.5/lib/rails/commands/commands_tasks.rb:68:in `console'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/railties-4.2.5/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/railties-4.2.5/lib/rails/commands.rb:17:in `<top (required)>'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:274:in `require'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:274:in `block in require'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:240:in `load_dependency'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:274:in `require'
from /Users/aa/dropbox/beginningRails/guideblogagain/bin/rails:9:in `<top (required)>'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:268:in `load'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:268:in `block in load'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:240:in `load_dependency'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:268:in `load'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/spring-1.6.4/lib/spring/commands/rails.rb:6:in `call'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/spring-1.6.4/lib/spring/command_wrapper.rb:38:in `call'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/spring-1.6.4/lib/spring/application.rb:185:in `block in serve'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/spring-1.6.4/lib/spring/application.rb:156:in `fork'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/spring-1.6.4/lib/spring/application.rb:156:in `serve'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/spring-1.6.4/lib/spring/application.rb:131:in `block in run'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/spring-1.6.4/lib/spring/application.rb:125:in `loop'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/spring-1.6.4/lib/spring/application.rb:125:in `run'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/spring-1.6.4/lib/spring/application/boot.rb:18:in `<top (required)>'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
Article.first.comments
是一个ActiveRecord_Associations_CollectionProxy
对象,类似于数组。如果你想为每条评论获取评论者,你可以使用 map
Article.first.comments.map(&:commenter)
或者您可以获得第一条评论的评论者:
Article.first.comments.first.commenter
与以下内容相同:
Article.first.comments.body # Won't work
Article.first.comments.map(&:body) # Returns an array (each comment's body)
Article.all.comments # Won't work
Article.all.map(&:comments) # Returns an array (each article's comments)
当您 运行 您的工作示例 Article.first.comments
时,请查看实际的 return 值。你看到了什么? return 是一个对象数组,对吧?所以说 Article.first
有 10 Comments
。当你 运行 你的查询时,ActiveRecord 会 return 你一个包含 10 Comment
个对象的数组。
现在让我们看一下您的一个无效示例。
说,Article.first.comments.commenter
。我们再次从 Article.first
开始,我们知道 return 是我们数据库中的第一个 Article
对象。
不过接下来要考虑Article.first.comments
。
我们已经确信这是一个 Comment
对象数组,对吧?问题就在这里——commenter
是单个 Comment
对象的属性。
但是您没有一个 Comment
对象——您有一个 Comment
个对象的数组,并且 commenter
没有在数组上定义。
Article.first.comments.body
问题是一样的。这有意义吗?
您可以在控制台中执行以下操作:
Article.first.comments.each do |comment|
puts comment.commenter
end
然后您可以获得所有 commenter/body 值。
使用这种思路,我认为您将能够让自己相信 Article.all.comments
的问题,但如果没有,请随时发表评论,我们可以讨论。
Here are the docs为Active Record关系,供参考。干杯!
对尝试从 Rails 控制台获取信息感到困惑
我有以下型号:Article
& Comment
。
对于 Article
,它是 has_many :comments
对于 Comment
,它是 belongs_to :article
让我们假设它们是关联的,并且是有效的。顺便说一下。
架构如下:
ActiveRecord::Schema.define(version: 20160312052519) do
create_table "articles", force: :cascade do |t|
t.string "title"
t.text "text"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "comments", force: :cascade do |t|
t.string "commenter"
t.text "body"
t.integer "article_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "comments", ["article_id"], name: "index_comments_on_article_id"
end
这些是路线:
resources :articles do
resources :comments
end
当我 运行 命令如下:
Article.first.comments
Comment.first.article
Comment.first.article.title
Comment.first.article.text
Comment.first.commenter
Comment.first.body
它们都有效。
但是当我尝试 运行 在 Articles
上进行反向操作时,例如:
Article.first.comments.commenter
Article.first.comments.body
Article.all.comments
它们不起作用。为什么不?
编辑
这是我在 运行 Article.first.comments.commenter
Article.first.comments.commenter
Article Load (23.0ms) SELECT "articles".* FROM "articles" ORDER BY "articles"."id" ASC LIMIT 1
NoMethodError: Comment Load (0.4ms) SELECT "comments".* FROM "comments" WHERE "comments"."article_id" = ? [["article_id", 1]]
undefined method `commenter' for #<Comment::ActiveRecord_Associations_CollectionProxy:0x007fa32b7e3d00>
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activerecord-4.2.5/lib/active_record/relation/delegation.rb:136:in `method_missing'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activerecord-4.2.5/lib/active_record/relation/delegation.rb:99:in `method_missing'
from (irb):127
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/railties-4.2.5/lib/rails/commands/console.rb:110:in `start'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/railties-4.2.5/lib/rails/commands/console.rb:9:in `start'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/railties-4.2.5/lib/rails/commands/commands_tasks.rb:68:in `console'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/railties-4.2.5/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/railties-4.2.5/lib/rails/commands.rb:17:in `<top (required)>'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:274:in `require'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:274:in `block in require'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:240:in `load_dependency'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:274:in `require'
from /Users/aa/dropbox/beginningRails/guideblogagain/bin/rails:9:in `<top (required)>'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:268:in `load'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:268:in `block in load'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:240:in `load_dependency'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:268:in `load'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/spring-1.6.4/lib/spring/commands/rails.rb:6:in `call'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/spring-1.6.4/lib/spring/command_wrapper.rb:38:in `call'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/spring-1.6.4/lib/spring/application.rb:185:in `block in serve'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/spring-1.6.4/lib/spring/application.rb:156:in `fork'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/spring-1.6.4/lib/spring/application.rb:156:in `serve'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/spring-1.6.4/lib/spring/application.rb:131:in `block in run'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/spring-1.6.4/lib/spring/application.rb:125:in `loop'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/spring-1.6.4/lib/spring/application.rb:125:in `run'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/spring-1.6.4/lib/spring/application/boot.rb:18:in `<top (required)>'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from /Users/aa/.rbenv/versions/2.1.4/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
Article.first.comments
是一个ActiveRecord_Associations_CollectionProxy
对象,类似于数组。如果你想为每条评论获取评论者,你可以使用 map
Article.first.comments.map(&:commenter)
或者您可以获得第一条评论的评论者:
Article.first.comments.first.commenter
与以下内容相同:
Article.first.comments.body # Won't work
Article.first.comments.map(&:body) # Returns an array (each comment's body)
Article.all.comments # Won't work
Article.all.map(&:comments) # Returns an array (each article's comments)
当您 运行 您的工作示例 Article.first.comments
时,请查看实际的 return 值。你看到了什么? return 是一个对象数组,对吧?所以说 Article.first
有 10 Comments
。当你 运行 你的查询时,ActiveRecord 会 return 你一个包含 10 Comment
个对象的数组。
现在让我们看一下您的一个无效示例。
说,Article.first.comments.commenter
。我们再次从 Article.first
开始,我们知道 return 是我们数据库中的第一个 Article
对象。
不过接下来要考虑Article.first.comments
。
我们已经确信这是一个 Comment
对象数组,对吧?问题就在这里——commenter
是单个 Comment
对象的属性。
但是您没有一个 Comment
对象——您有一个 Comment
个对象的数组,并且 commenter
没有在数组上定义。
Article.first.comments.body
问题是一样的。这有意义吗?
您可以在控制台中执行以下操作:
Article.first.comments.each do |comment|
puts comment.commenter
end
然后您可以获得所有 commenter/body 值。
使用这种思路,我认为您将能够让自己相信 Article.all.comments
的问题,但如果没有,请随时发表评论,我们可以讨论。
Here are the docs为Active Record关系,供参考。干杯!