未定义的方法' column_names'在创建模型实例时

时间:2015-05-10 14:12:54

标签: ruby-on-rails ruby-on-rails-4

我目前正在使用rails来构建管理Web应用程序。在我的应用程序环境中,玩家必须完成任务才能获得奖励。每个任务都有一定数量的任务要完成,然后才允许玩家获得奖励。

以前,任务和任务数据保存在.txt文件中,现在已移至数据库结构。我的应用程序必须提供的功能之一是读取.txt文件并将数据加载到数据库。

这是我的任务模型和架构:

型号:

class QuestTask < ActiveRecord::Base
    self.table_name = 'quest_task'
    self.primary_key = :task_id

    has_many :player_task_progresses, :class_name => 'PlayerTaskProgress', :foreign_key => :task_id
    belongs_to :quest, :class_name => 'Quest', :foreign_key => :quest_id
    has_many :quest_task_texts, :class_name => 'QuestTaskText', :foreign_key => :task_id
end

架构:

create_table "quest_task", primary_key: "task_id", force: :cascade do |t|
  t.integer "quest_id",      limit: 4,                null: false
  t.integer "task_type",     limit: 4,                null: false
  t.integer "foreign_id",    limit: 4,  default: 0,   null: false
  t.string  "class",         limit: 64
  t.integer "amount",        limit: 4,  default: 0,   null: false
  t.string  "coordinates",   limit: 64
  t.float   "trigger_range", limit: 24, default: 0.0
end

每次我尝试运行QuestTask.create时,都会抛出以下错误:

NoMethodError (undefined method `column_names' for nil:NilClass)

在控制器中的以下代码中:

data = {
    :quest_id => id,
    :exp_reward => d[key]['Exp'].to_i,
    :cash_reward => d[key]['Cash'].to_i,
    :pill_reward => d[key]['Gems'].to_i,
    :required_quest => d[key]['RequiredQuest'].to_i,
    :npc_id => d[key]['Survivor'].to_i,
    :player_needs_clan => d[key]['ClanRequired'].to_i,
    :required_level => d[key]['MinLevel'].to_i
}
begin
    quest = Quest.find(data[:quest_id])
    quest.update(data)
rescue ActiveRecord::RecordNotFound
    quest = Quest.create(data)
end

#Task string example c:32:15|u:npc_sara
tasks = d[key]['Tasks'].split('|')
tasks.each do |task|
    tdata = {:task_id => nil,
        :quest_id => id
    }
    info = task.split(':')
    if info[0] == 'c'
        tdata[:task_type] = 1
        tdata[:foreign_id] = info[1].to_i
        tdata[:amount] = info[2].to_i
    elsif info[0] == 'k'
        tdata[:task_type] = 2
        tdata[:class] = info[1]
        tdata[:amount] = info[2].to_i
        if info[3] != '__NONE__'
            data[:map] = info[3]
        end
        tdata[:coordinates] = info[4]
        tdata[:trigger_range] = info[5]
    elsif info[0] == 'u'
        tdata[:task_type] = 4
        tdata[:class] = info[1]
        tdata[:amount] = 1
    elsif info[0] == 'w'
        tdata[:task_type] = 5
        tdata[:class] = info[1]
        tdata[:amount] = 1
    elsif info[0] = 'x'
        tdata[:task_type] = 6
        tdata[:class] = info[1]
    end
    print tdata
    res = QuestTask.find_by(quest_id: id.to_s)
    if res == nil
        print tdata
        QuestTask.create(tdata)
    else
        res.delete()
        QuestTask.create(tdata)
    end

在前面的代码中,变量d是在解析数据文件后构建的散列,变量id是用户输入。

作为一个例子,我得到的最后一个tdata是:

{:task_id=>nil, :quest_id=>1, :task_type=>1, :foreign_id=>15, :amount=>5}

将task_id更改为数字没有区别(无论如何都设置为auto_increment)。

为什么会抛出错误?

1 个答案:

答案 0 :(得分:1)

create_table "quest_task", primary_key: "task_id", force: :cascade do |t|
  t.integer "quest_id",      limit: 4,                null: false
  t.integer "task_type",     limit: 4,                null: false
  t.integer "foreign_id",    limit: 4,  default: 0,   null: false
->t.string  "class",         limit: 64
  t.integer "amount",        limit: 4,  default: 0,   null: false
  t.string  "coordinates",   limit: 64
  t.float   "trigger_range", limit: 24, default: 0.0
end

更改列名,类是保留字。