我有两个模型对象 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 接收,生成的查询有 _id。我唯一的想法是我对具有多个单词名称的资源做错了-是否有关于多个单词名称约定的好的文档?
架构.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
从视图来看,这是表单部分 - 这就是创建参数的原因吗?
<%= 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 似乎应该能够推断出相关数据库列的名称。对数据库列的名称进行编码似乎很脆弱。难道我做错了什么?