根据指定规格编写控制器和模型 Ruby 代码
Write Controller and Model Ruby Code Based On Specified Specs
我必须根据提供的规范编写 Ruby 代码,并在我 运行 代码时使规范中指定的测试通过。
提供的规范如下:
describe Product, type: :model do
let!(:product) { Product.create(name: 'Hammer', category: 'Tools', price: 10.99) }
describe ".search" do
subject { Product.search(term) }
context "has result" do
context "term in name" do
let(:term) { "hammer" }
it { is_expected.to eq([product]) }
end
context "term in category" do
let(:term) { "tool" }
it { is_expected.to eq([product]) }
end
end
context "has no result" do
let(:term) { "nail" }
it { is_expected.to eq([]) }
end
end
end
describe ProductsController, type: :controller do
let!(:product) { Product.create(name: 'Blue shoes', category: 'Footwear', price: 10.99) }
let!(:response) { RequestHelpers.execute('GET', ProductsController, 'search', {term: 'Shoe', format: :json}) }
describe "#search" do
it "returns json" do
first_product = JSON.parse(response.body).first
expect(first_product['name']).to eq 'Blue shoes'
expect(first_product['category']).to eq 'Footwear'
expect(first_product['price']).to eq '10.99'
end
end
end
我写了下面的代码:
class ProductsController < ActionController::Base
def create
@product = Product.new(product_params)
render json: @product
end
def search
@products = Product.search(params[:search])
render json: @products
end
private
def product_params
params.require(:product).permit(:name, :category, :price)
end
end
class Product < ActiveRecord::Base
validates_presence_of :name, :category, :price
def self.search(search)
where('name LIKE ?', "%#{search}%")
end
end
我希望所有测试都能通过
但是,当我 运行 代码时,我得到以下堆栈跟踪:
Test Results:
Log
-- create_table(:products)
-> 0.0047s
Product
.search
has result
term in name
example at ./spec.rb:10
term in category
example at ./spec.rb:15
Test Failed
expected: [#<Product id: 1, name: "Hammer", category: "Tools", price: 0.1099e2, created_at: "2019-04-12 19:01:03", updated_at: "2019-04-12 19:01:03">]
got: #<ActiveRecord::Relation []>
(compared using ==)
Diff:
@@ -1,2 +1,2 @@
-[#<Product id: 1, name: "Hammer", category: "Tools", price: 0.1099e2, created_at: "2019-04-12 19:01:03", updated_at: "2019-04-12 19:01:03">]
+[]
has no result
example at ./spec.rb:21
ProductsController
#search
returns json
我的代码实现哪里可能出错?
您的语法:
find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
似乎是 old/deprecated(参见 this Q&A)。相反,也许,尝试这样的事情:
class Product < ActiveRecord::Base
validates_presence_of :name, :category, :price
def self.search(search)
if search
where('name LIKE ?', "%#{search}%")
else
all
end
end
end
where
语法可能需要也可能不需要一些修改,因为我没有测试它。如果有误,可能会有人指出。
此外,您将 search
方法定义为:
def self.search(search)
...
end
这意味着 search
参数是必需的。但是,然后您在此处测试 search
是否存在:
if search
where('name LIKE ?', "%#{search}%")
else
all
end
这没有什么意义,因为 search
是必需的。您应该 (1) 删除 if
条件或 (2) 通过执行以下操作使 search
可选:
def self.search(search=nil)
...
end
根据您的编辑,您的 "term in category" 测试失败了,因为您只搜索 name
字段,此处:
where('name LIKE ?', "%#{search}%")
您没有像 "tool" 这样 name
的产品,所以您的结果是 return 一个空结果集 - 这就是错误告诉您的。
尝试更像:
where('name LIKE :search OR category LIKE :search', search: "%#{search}%")
同样,您可能必须 fiddle 使用该语法。
我必须根据提供的规范编写 Ruby 代码,并在我 运行 代码时使规范中指定的测试通过。 提供的规范如下:
describe Product, type: :model do
let!(:product) { Product.create(name: 'Hammer', category: 'Tools', price: 10.99) }
describe ".search" do
subject { Product.search(term) }
context "has result" do
context "term in name" do
let(:term) { "hammer" }
it { is_expected.to eq([product]) }
end
context "term in category" do
let(:term) { "tool" }
it { is_expected.to eq([product]) }
end
end
context "has no result" do
let(:term) { "nail" }
it { is_expected.to eq([]) }
end
end
end
describe ProductsController, type: :controller do
let!(:product) { Product.create(name: 'Blue shoes', category: 'Footwear', price: 10.99) }
let!(:response) { RequestHelpers.execute('GET', ProductsController, 'search', {term: 'Shoe', format: :json}) }
describe "#search" do
it "returns json" do
first_product = JSON.parse(response.body).first
expect(first_product['name']).to eq 'Blue shoes'
expect(first_product['category']).to eq 'Footwear'
expect(first_product['price']).to eq '10.99'
end
end
end
我写了下面的代码:
class ProductsController < ActionController::Base
def create
@product = Product.new(product_params)
render json: @product
end
def search
@products = Product.search(params[:search])
render json: @products
end
private
def product_params
params.require(:product).permit(:name, :category, :price)
end
end
class Product < ActiveRecord::Base
validates_presence_of :name, :category, :price
def self.search(search)
where('name LIKE ?', "%#{search}%")
end
end
我希望所有测试都能通过
但是,当我 运行 代码时,我得到以下堆栈跟踪:
Test Results:
Log
-- create_table(:products)
-> 0.0047s
Product
.search
has result
term in name
example at ./spec.rb:10
term in category
example at ./spec.rb:15
Test Failed
expected: [#<Product id: 1, name: "Hammer", category: "Tools", price: 0.1099e2, created_at: "2019-04-12 19:01:03", updated_at: "2019-04-12 19:01:03">]
got: #<ActiveRecord::Relation []>
(compared using ==)
Diff:
@@ -1,2 +1,2 @@
-[#<Product id: 1, name: "Hammer", category: "Tools", price: 0.1099e2, created_at: "2019-04-12 19:01:03", updated_at: "2019-04-12 19:01:03">]
+[]
has no result
example at ./spec.rb:21
ProductsController
#search
returns json
我的代码实现哪里可能出错?
您的语法:
find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
似乎是 old/deprecated(参见 this Q&A)。相反,也许,尝试这样的事情:
class Product < ActiveRecord::Base
validates_presence_of :name, :category, :price
def self.search(search)
if search
where('name LIKE ?', "%#{search}%")
else
all
end
end
end
where
语法可能需要也可能不需要一些修改,因为我没有测试它。如果有误,可能会有人指出。
此外,您将 search
方法定义为:
def self.search(search)
...
end
这意味着 search
参数是必需的。但是,然后您在此处测试 search
是否存在:
if search
where('name LIKE ?', "%#{search}%")
else
all
end
这没有什么意义,因为 search
是必需的。您应该 (1) 删除 if
条件或 (2) 通过执行以下操作使 search
可选:
def self.search(search=nil)
...
end
根据您的编辑,您的 "term in category" 测试失败了,因为您只搜索 name
字段,此处:
where('name LIKE ?', "%#{search}%")
您没有像 "tool" 这样 name
的产品,所以您的结果是 return 一个空结果集 - 这就是错误告诉您的。
尝试更像:
where('name LIKE :search OR category LIKE :search', search: "%#{search}%")
同样,您可能必须 fiddle 使用该语法。