Skip to content

Instantly share code, notes, and snippets.

@bunyan
Last active October 14, 2020 13:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bunyan/1ea31f8b6ce8290c50b6 to your computer and use it in GitHub Desktop.
Save bunyan/1ea31f8b6ce8290c50b6 to your computer and use it in GitHub Desktop.
Rails 4.2: composite_primary_keys 8.1.0 and activerecord-sqlserver-adapter 4.2.4 generating wrong SQL on some queries
class CreateNoIdModels < ActiveRecord::Migration
def change
create_table :no_id_models, id: false do |t|
t.integer :pk1
t.integer :pk2
end
end
end
source 'https://rubygems.org'
gem 'rails', '4.2.3'
gem 'composite_primary_keys', '8.1.0'
gem 'activerecord-sqlserver-adapter', '4.2.4'
gem 'tiny_tds', '0.6.2'
class NoIdModel < ActiveRecord::Base
self.primary_keys = [:pk1, :pk2]
end
require 'test_helper'
class NoIdModelTest < ActiveSupport::TestCase
test 'model with no id limited by 1' do
assert NoIdModel.limit(1).to_a.is_a?(Array)
end
end
NoIdModel.create([{ pk1: 1, pk2: 2 }, { pk1: 3, pk2: 4 }])
# put this in the initializers folder
# requires Ruby 2+
module SQLServerCPKOrderFix
def make_Fetch_Possible_And_Deterministic o
super
o.orders.each_with_index do |node, i|
rel = node.expr.relation
expr_name = node.expr.name
if expr_name.is_a?(CompositePrimaryKeys::CompositeKeys)
o.orders[i] = expr_name.collect { |a| rel[a].send(node.direction) }
end
end
end
end
Arel::Visitors::SQLServer.prepend(SQLServerCPKOrderFix)
@hechien
Copy link

hechien commented Aug 18, 2020

Thanks for this solution.

By the way, for ActiveRecord 6 with Ruby (not Rails, only ActiveRecord 6 and tiny_tds and SQLServer adapter), the line 10 of ~arel_cpk_sqlserver_order_fix.rb might should be changed to:

if expr_name.is_a?(Array)

@dvergeylen
Copy link

Thanks for this solution. Tested with activerecord 6.0.3.4 👍
Had to update line 10 as @hechien suggested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment