2015-05-10 3 views
1

В настоящее время я работаю в rails для создания административного webapp. В моем контексте приложения есть квесты, которые игроки должны заполнить, чтобы заработать награды. У каждого квеста задано определенное количество задач, прежде чем разрешить игрокам претендовать на награду.undefined method 'column_names' при создании экземпляра модели

Раньше данные квеста и задач сохранялись в 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 в любом случае).

Почему это ошибка?

+0

Эта часть кода не имеет проблем, и она находит запись квеста в базе данных. Если этого не существует, то я уже поймал исключение NotFound и создал его вместо обновления. Проблема заключается в самом конце кода, который я опубликовал – felipeimm

ответ

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 

Изменить название столбца, класс - зарезервированное слово.

Смежные вопросы