我在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_parts'方法来执行排序并从has_many中删除顺序。我不得不改变所有控制器来调用'ordered_parts'而不是'parts'方法。当然有更好的方法。如果有人知道,请帮助。
def ordered_parts
self.parts.order('name asc')
end