RoR - SQLite3 :: SQLException:没有这样的列: - Rails没有将_id附加到生成的查询

时间:2013-09-06 14:57:37

标签: ruby-on-rails sqlite

我有两个模型对象LineItemClass和LineItemSubClass。我试图将新的LineItemSubClass添加到LineItemClass,它正在生成SQL错误:

SQLite3::SQLException: no such column: line_item_sub_classes.line_item_class.

正确的查询应该更像line_item_sub_classes.line_item_class_id

我使用generate来创建所有内容,所以我对于为什么会发生这种情况感到非常困惑。在研究问题时,在我看到SQL eception的其他地方,生成的查询都有_id。我唯一的想法是,我对使用多个单词名称的资源做错了 - 是否有关于多个单词名称的约定的好文档?

schema.rb

ActiveRecord::Schema.define(:version => 20130905194234) do
  create_`enter code here`table "line_item_classes", :force => true do |t|
    t.string   "code"
    t.string   "name"
    t.datetime "created_at", :null => false
    t.datetime "updated_at", :null => false
  end

  create_table "line_item_sub_classes", :force => true do |t|
    t.string   "code"
    t.string   "name"
    t.integer  "line_item_class_id"
    t.datetime "created_at",         :null => false
    t.datetime "updated_at",         :null => false
  end

  add_index "line_item_sub_classes", ["line_item_class_id"], :name =>"index_line_item_sub_classes_on_line_item_class_id"
end

line_item_class.rb

class LineItemClass < ActiveRecord::Base 
  include ActiveModel::ForbiddenAttributesProtection

  has_many :line_item_sub_classes

  attr_accessible :code, :name

  validates :code, presence: true, length: {is: 2}, uniqueness: true
  validates :name, presence: true, length: {maximum: 100}, uniqueness: true
end

line_item_sub_class.rb

class LineItemSubClass < ActiveRecord::Base
  include ActiveModel::ForbiddenAttributesProtection

  belongs_to :line_item_class

  attr_accessible :code, :name

  validates :code, presence: true, length: {is: 2}, :uniqueness => {:scope => :line_item_class}
  validates :name, presence: true, length: {maximum: 100}, :uniqueness => {:scope => :line_item_class}
end

来自line_item_sub_classes_controller.rb

的违规代码
class LineItemSubClassesController < ApplicationController
  def create
    @line_item_class = LineItemClass.find(params[:line_item_class_id])
    @line_item_sub_class = 
      @line_item_class.line_item_sub_classes.
      create(params[:line_item_sub_class].permit(:code, :name))
    redirect_to line_item_class_path(@line_item_class)
  end
end

从视图来看,这里是表单部分 - 这是创建params的权利吗?

<%= form_for([@line_item_class,
              @line_item_class.line_item_sub_classes.build]) do |f| %>
  <p>
    <%= f.label :code %><br />
    <%= f.text_field :code %>
  </p>
  <p>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </p>
  <p>
    <%= f.submit %>
  </p>
<% end %>

输出html中的表单标记是

<form accept-charset="UTF-8" action="/line_item_classes/1/line_item_sub_classes" class="new_line_item_sub_class" id="new_line_item_sub_class" method="post">

控制器在行

中生成错误
@line_item_sub_class = @line_item_class.line_item_sub_classes.create(params[:line_item_sub_class].permit(:code, :name))

我试过把它分成两行,但没有帮助。更新行抛出了一个nil对象异常。

@line_item_sub_class =@line_item_class.line_item_sub_classes.new
@line_item_sub_class.update_attributes(params[:line_item_sub_class].permit(:code, :name))

完全错误是;

SQLite3::SQLException: no such column: line_item_sub_classes.line_item_class: SELECT 1 AS one FROM "line_item_sub_classes" WHERE ("line_item_sub_classes"."code" = 'A0' AND "line_item_sub_classes"."line_item_class" IS NULL) LIMIT 1. 

我不知道railsmagic在这里做了什么,但我无法想象为什么这个查询会被需要。似乎在记录存在之后才能运行。

答案 - 排序...... 我通过更改LineItemSubClass模型中唯一性验证器的范围来修复错误。

  validates :code, presence: true, length: {is: 2}, :uniqueness => {:scope => :line_item_class}
  validates :name, presence: true, length: {maximum: 100}, :uniqueness => {:scope => :line_item_class}

现在是

  validates :code, presence: true, length: {is: 2}, :uniqueness => {:scope => :line_item_class_id}
  validates :name, presence: true, length: {maximum: 100}, :uniqueness => {:scope => :line_item_class_id}

这很有效。我现在可以创建一个没有错误的嵌套LineItemSubClass,但我的RoR感觉刺痛。当我将唯一性范围扩展到现有关联时,似乎Rails应该能够推断出相关数据库列的名称。编写数据库列的名称似乎很脆弱。我做错了吗?

1 个答案:

答案 0 :(得分:0)

所以,你的参数是:

{ "utf8"=>"✓", 
  "authenticity_token"=>"Lj8iy9VkzdWrvN4LyzXQ5BY7FdpV57l12Euqtch9RtQ=",
  "line_item_sub_class"=>{   // These are the only parameters that will get
    "code"=>"A0",            // considered when creating your new
    "name"=>"Panel Box"      // LineItemSubClass record in the DB
  }, 
  "commit"=>"Create Line item sub class",
  "action"=>"create",
  "controller"=>"line_item_sub_classes",
  "line_item_class_id"=>"1"  // But this parameter needs to be included
                             // needs to be included to set the
                             // line_item_sub_classes.line_item_class_id field
}

看起来,在您的控制器中,您正在使用params[:line_item_sub_class]来创建新记录。所以,我认为首先你需要改变你的形式,以便......

params[:line_item_class_id]

......实际上是

params[:line_item_sub_class][:line_item_class_id]

这将带你到那里的一部分。但是,我认为这不一定会解决您的整个问题。你能用:

更新你的问题吗?
  1. 此操作的SQL查询输出称为
  2. 您收到此错误的文件名和行号
  3. 如果需要,可以在调用此控制器操作时发布整个rails日志输出。感谢那将彻底揭开神秘面纱(我希望)来解决它。

    说这个的另一种方式是你的表单传递的参数结构似乎与控制器的预期不符,这可能是大多数问题。所以,不管你信不信,看看你的视图,它产生的HTML,并试图弄清楚为什么它中的参数与结构和命名方面的轨道不匹配。如果你能解决这个问题,你将会在那里大部分时间。