我有这个密码。rails的第一条和第二条命令运行良好,但是"project.todos << todo“部件ruby解释器将其视为错误。
NoMethodError: undefined method `todos' for nil:NilClass我怎么才能修好它?当我输入像这样的seeds.rb文本时,一切都很好,但使用代码却不起作用:
#work
project = Project.create title: "Family"
todo = Todo.create text: "Buy milk", isCompleted: true
project.todos << todo
#code
require 'yaml'
yhash = YAML.load_file(File.open("#{Rails.root}/db/seeds.yml"))
yhash.each do |key, value|
value.each do |k, v|
k.each do |ke, proj|
if proj.class.name == 'String'
project = Project.create title: proj
elsif proj.class.name == 'Array'
proj.each do |todo|
i = 0
tmp = ''
todo.each do |to|
to.each do |t|
if i == 0
i = 1
elsif i == 2
i = 3
elsif i == 1
tmp = t
i = 2
elsif i == 3
if t == false
bool = 'false'
else
bool = 'true'
end
todo = Todo.create text: tmp, isCompleted: bool
project.todos << todo
i = 0
tmp = ''
end
end
end
end
end
end
end
end发布于 2017-02-01 09:30:52
简短回答
你真的应该改变你的YAML结构,这会使一切变得容易得多。
---
projects:
- title: Family
todos:
- text: Buy milk
is_completed: true
- text: Todo2
is_completed: false
- title: Project2
todos:
- text: Todo3
is_completed: true
- text: Todo4
is_completed: false您可以用几行代码解析它:
yaml = YAML.load(File.read('test.yaml'))
yaml['projects'].each do |project|
title = project['title']
p title
# Create project here
project['todos'].each do |todo|
p todo
# Create todo here
# Add todo to project
end
endNoMethodError
NoMethodError: undefined method 'todos' for nil:NilClass意味着没有定义调用todos的对象(project)。
实际上,project没有定义,但是proj是定义的,所以您应该首先创建一个名为project的Project。
命名对象
为了避免混淆:
project_name可以是包含项目名称的字符串。project_names可以是项目名称的数组。project可以是Project对象todos可以是Todo的数组您的代码指示proj用于不同目的:
project = Project.create title: proj
proj.each do |todo|这两个proj应该是不同的对象,具有不同的变量名,并且应该单独初始化。
在YAML中编写嵌套散列很容易,一个哈希可以表示Project,另一个可以表示Todo。
块变量
如果在第一次迭代期间在循环中创建一个名为project的project实例,则下一次迭代将无法使用它:
[1, 2, 3].each do |i|
if i==1
project = "my project"
end
p i
p project
end
# 1
# "my project"
# 2
# nil
# 3
# nil如果希望project变量对所有迭代都可用,则应该在循环的之外创建它:
project = "my project"
[1, 2, 3].each do |i|
p i
p project
end
# 1
# "my project"
# 2
# "my project"
# 3
# "my project"另一种可能是使用@project而不是project:
[1,2,3].each do |i|
if i==1
@project = "my project"
end
p i
p @project
end
# 1
# "my project"
# 2
# "my project"
# 3
# "my project"案例
而不是:
if proj.class.name == 'String'
project = Project.create title: proj
elsif proj.class.name == 'Array'你可以用:
case proj
when String
# proj is a String
when Array
# proj is an Array
endhttps://stackoverflow.com/questions/41976148
复制相似问题