根据指定的规范编写控制器和模型Ruby代码

问题描述 投票:0回答:1

我必须根据提供的规范编写Ruby代码,并在运行代码时生成spec规范中指定的测试。提供的规格如下:

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

我的代码实现在哪里可能出错?

ruby-on-rails rspec-rails
1个回答
1
投票

你的语法:

find(:all, :conditions => ['name LIKE ?', "%#{search}%"])

似乎是旧的/弃用的(参见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

根据您的编辑,您的“类别中的术语”测试失败,因为您只搜索name字段,此处:

where('name LIKE ?', "%#{search}%")

你没有像“工具”这样的name产品,所以你的结果是返回一个空的结果集 - 这就是错误告诉你的。

尝试更像的东西:

where('name LIKE :search OR category LIKE :search', search: "%#{search}%")

同样,您可能不得不摆弄这种语法。

© www.soinside.com 2019 - 2024. All rights reserved.