Rails:has_many:通过模型中的排序顺序问题

时间:2015-11-22 17:39:10

标签: ruby-on-rails-4 associations rspec-rails

我在Rails模型中有一些奇怪的行为,我不太清楚为什么。感谢任何能指出我缺少或不理解的人。

问题

我有一辆带有has_many的车型:通过关于零件通过CarsPart的关系。我希望按照字母顺序访问汽车的零件。我创建了模型规格和控制器规格。在控制器中,部件按字母顺序排序,如has_many关系中所述。在控制器规范中,它们是有序的。在型号规格中,它们不是。我不认为它与测试框架有关,因为我调试了正在运行的服务器并看到了相同的行为。

守则

汽车

class Car < ActiveRecord::Base

  has_many :cars_parts
  has_many :parts, -> { order('name asc') }, through: :cars_parts, :dependent => :destroy

  accepts_nested_attributes_for :cars_parts, :allow_destroy => true

  validates :make, :model, presence: true

  validate :validate_cars_parts

  def validate_cars_parts
    errors.add(:parts, "wrong number") if self.cars_parts.size < 1

    self.cars_parts.each do |car_part|
      part = Part.find(car_part.part_id)
      errors.add(:parts, "doesn't exist") if part == nil
    end
  end
end

部分

class Part < ActiveRecord::Base

  belongs_to :cars_part
  has_many :cars, through: :cars_parts

  validates :name, presence: true

end

CarsPart

class CarsPart < ActiveRecord::Base

  belongs_to :car
  belongs_to :part

end

汽车控制器规格 通过

require 'rails_helper'

RSpec.describe CarsController, type: :controller do
  render_views

  context 'property features' do

    describe "GET #show/id returns ordered parts" do

      before :each do
        @p4 = FactoryGirl.create(:part, :name => 'BPart2')
        @p3 = FactoryGirl.create(:part, :name => 'APart2')

        @p6 = FactoryGirl.create(:part, :name => 'BPart3')
        @p5 = FactoryGirl.create(:part, :name => 'APart3')

        @p2 = FactoryGirl.create(:part, :name => 'BPart1')
        @p1 = FactoryGirl.create(:part, :name => 'APart1')
      end

      it 'returns parts in alphabetical order' do
        car = FactoryGirl.create(:car, make: 'Nissan', model: 'Murano', parts: [@p4, @p3, @p6, @p5, @p2, @p1])

        get :show, id: car.id, format: :json
        expect(response).to have_http_status(:success)
        expect(response).to render_template(:show)

        response_json = JSON.parse(response.body)

        response_json['parts'].each do |part|
          puts part['id']
        end

        expect(response_json['parts'].size).to eq(6)
        expect(response_json['parts'][0]['id']).to eq(@p1.id)
        expect(response_json['parts'][1]['id']).to eq(@p3.id)
        expect(response_json['parts'][2]['id']).to eq(@p5.id)
        expect(response_json['parts'][3]['id']).to eq(@p2.id)
        expect(response_json['parts'][4]['id']).to eq(@p4.id)
        expect(response_json['parts'][5]['id']).to eq(@p6.id)
      end

    end

  end
end

汽车型号规格 失败

require 'rails_helper'

RSpec.describe Car, type: :model do

  context 'car parts' do

    before :each do
      @p4 = FactoryGirl.create(:part, :name => 'BPart2')
      @p3 = FactoryGirl.create(:part, :name => 'APart2')

      @p6 = FactoryGirl.create(:part, :name => 'BPart3')
      @p5 = FactoryGirl.create(:part, :name => 'APart3')

      @p2 = FactoryGirl.create(:part, :name => 'BPart1')
      @p1 = FactoryGirl.create(:part, :name => 'APart1')

    end

    it 'returns parts in alphabetical order' do
      car = FactoryGirl.create(:car, make: 'Nissan', model: 'Murano', parts: [@p4, @p3, @p6, @p5, @p2, @p1])

      expect(car).to be_valid
      expect(car.errors.messages.size).to eq(0)
      expect(car.parts.size).to eq(6)

      car.parts.each do |part|
        puts part.id
      end

      expect(car.parts[0]['name']).to eq('APart1')
      expect(car.parts[1]['name']).to eq('APart2')
      expect(car.parts[2]['name']).to eq('APart3')
      expect(car.parts[3]['name']).to eq('BPart1')
      expect(car.parts[4]['name']).to eq('BPart2')
      expect(car.parts[5]['name']).to eq('BPart3')
    end

  end

end

摘要 请帮助我理解为什么当通过模型访问它们时,它们没有被订购,但是当控制器查找并呈现它们时,它们就是。

谢谢。

修改

我设法让这个工作的唯一方法是创建一个'ordered_pa​​rts'方法来执行排序并从has_many中删除顺序。我不得不改变所有控制器来调用'ordered_pa​​rts'而不是'parts'方法。当然有更好的方法。如果有人知道,请帮助。

  def ordered_parts
    self.parts.order('name asc')
  end

0 个答案:

没有答案