【发布时间】:2013-12-20 04:00:13
【问题描述】:
在 Sequel Pro 中,使用以下语句创建了一个表:
CREATE TABLE dogs(
id INT PRIMARY KEY NOT NULL,
name TEXT,
color TEXT
);
*auto increment, under extra in structures, is checked so Sequel Pro generate primary keys automatically*
使用 mysql2,我在 ruby 文件 classdog.rb 中编写了方法 insert,用于将新狗插入到表狗中。
classdog.rb 全文如下:
require 'mysql2'
require "debugger"
class Dog
attr_accessor :name, :color, :id,
@@db = Mysql2::Client.new(:host => '127.0.0.1', :username => 'root', :database => 'dogs')
def initialize(name, color)
@name = name
@color = color
end
def self.db
@@db
end
def db
@@db
end
def insert
db.query("INSERT INTO dogs(name, color) VALUE('#{name}', '#{color}')")
end
end
dog = Dog.new("simba", "grey")
puts dog.insert
为了检查我的代码是否正常工作,我创建了这个 rspec 文件:
require "./classdog"
describe Dog do
describe "#insert" do
it "should insert a dog into the database" do
dog = Dog.new("simba", "grey")
sql_command = "SELECT * FROM dogs WHERE name = '#{dog.name}'";
row_hash = {"id" => 1, "name" => "simba", "color" => "grey"}
expect(Dog.db.query(sql_command).first).to eq(row_hash)
end
end
end
当我使用以下命令在 ruby 中运行我的规范文件时:
rspec spec_classdog.rb
我的测试通过了。
但有两件事我不明白:
-
当我使用 rspec 运行我的规范文件 spec_classdog.rb 时,表本身只会插入一条新狗。但是当我运行我的 ruby 文件 classdog.rb 时,没有插入新的狗。
- 为什么会这样?我预计运行我的 ruby 文件可能会导致新的插入,而 rspec 只是为了检查以确保我的方法有效。这是因为我没有将参数名称和颜色传递给 insert 方法(意思是这样的:dog.insert("spot", "black")?
-
当我的 classdog.rb 文件中有以下代码时:
dog = Dog.new("simba", "grey") puts dog.inspect puts dog.name puts dog.color puts dog.id
Ruby 提出:
请注意 dog.id 没有输出,如下所示:
dog = Dog.new("simba", "grey")
puts dog.id
- 为什么 ruby 不显示 dog.id 中 dog 的 id?
- 是因为在创建 TABLE dog 时将 id 设置为主键吗?
- 添加一个名为 dog_id 的特定列会有帮助吗?
@PeterAlfvin:这是显示运行 puts dog.insert 的输出的图像
【问题讨论】:
-
您在这里编写自己的 ORM 并犯了很多严重错误。 Proper escaping 不是可选的。为什么要走这条路而不是使用ActiveRecord、Sequel 或Data Mapper?您不应该使用字符串插值来编写查询,这完全是鲁莽的。不建议直接针对
mysql2库编写。 -
如果您希望将此作为学术练习,那很好,但在编写查询时要格外小心。
-
@tadman:这纯粹是一个学术练习,但我仍然想知道在实践中是如何完成的(宁愿养成好习惯也不愿养成坏习惯)。将查找正确的转义和数据映射器;还没有学过 Rails,所以没有 ActiveRecord。如果您能就我的问题提供反馈,将不胜感激。谢谢!
-
为什么您认为仅运行 classdog 时不会发生数据库插入?
-
每次我简单地运行 classdog.rb 时,我都会刷新我的表,但我看不到任何变化。当我运行 rspec spec_classdog.rb 时,我刷新了我的表,我看到表中添加了一条新狗。