在has_many中使用uniq函数时出现TinyTDS错误

时间:2014-06-15 22:39:01

标签: ruby-on-rails sql-server tiny-tds

我目前正在投放:

Windows 7 64-bit
Rails 4.1.1
Ruby 2.0.0p481
tiny_tds [gem] 0.6.2

我已经成功启动了一个rails应用程序来访问远程SQL Server(我不确定服务器的版本是什么)。我有一个模型,resource.rb,具有以下关联:

class Resource < ActiveRecord::Base
    self.table_name = 'tResources'
    self.primary_key = 'emp_Id'

    has_many :project_resources, foreign_key: 'emp_Id'
    has_many :projects, through: :project_resources
    ...

    default_scope { order("#{Resource.table_name}.lastname ASC") }
    ...

模型project_resource.rb具有以下内容:

class ProjectResource < ActiveRecord::Base
    self.table_name = 'tProject_Resources'
    self.primary_key = 'key_Id'

    belongs_to :project
    belongs_to :resource, foreign_key: 'emp_Id'
    belongs_to :calendar
    ...

这一切都很棒。如果我有资源r,我可以通过引用r获取与r.projects相关联的所有项目。但是,此关联中有一些重复的项目,因此在我看来,我目前正在成功使用r.projects.uniq

我想将uniq移动到has_many,如下所示:

has_many :projects, -> { uniq }, through: :project_resources

通过这种方式定义关联,我尝试成功的唯一r.projects引用是r.projects.count,它确实为我提供了资源r的唯一项目的准确计数

但是,其他引用(例如简单r.projects)会产生TinyTDS错误:

irb(main):010:0> r.projects
  Project Load (290.0ms)  EXEC sp_executesql N'SELECT DISTINCT *, __order FROM (
 SELECT [tProjects].*, DENSE_RANK() OVER (ORDER BY name ASC) AS __order, ROW_NUM
BER() OVER (PARTITION BY [tProjects].* ORDER BY name ASC) AS __joined_row_num FR
OM [tProjects] INNER JOIN [tProject_Resources] ON [tProjects].[project_Id] = [tP
roject_Resources].[project_id] WHERE [tProject_Resources].[emp_Id] = @0 ) AS __s
q WHERE __joined_row_num = 1 ORDER BY __order', N'@0 int', @0 = 471  [["emp_Id",
 471]]
TinyTds::Error: Incorrect syntax near '*'.: EXEC sp_executesql N'SELECT DISTINCT
 *, __order FROM ( SELECT [tProjects].*, DENSE_RANK() OVER (ORDER BY name ASC) A
S __order, ROW_NUMBER() OVER (PARTITION BY [tProjects].* ORDER BY name ASC) AS _
_joined_row_num FROM [tProjects] INNER JOIN [tProject_Resources] ON [tProjects].
[project_Id] = [tProject_Resources].[project_id] WHERE [tProject_Resources].[emp
_Id] = @0 ) AS __sq WHERE __joined_row_num = 1 ORDER BY __order', N'@0 int', @0
= 471
ActiveRecord::StatementInvalid: TinyTds::Error: Incorrect syntax near '*'.: EXEC
 sp_executesql N'SELECT DISTINCT *, __order FROM ( SELECT [tProjects].*, DENSE_R
ANK() OVER (ORDER BY name ASC) AS __order, ROW_NUMBER() OVER (PARTITION BY [tPro
jects].* ORDER BY name ASC) AS __joined_row_num FROM [tProjects] INNER JOIN [tPr
oject_Resources] ON [tProjects].[project_Id] = [tProject_Resources].[project_id]
 WHERE [tProject_Resources].[emp_Id] = @0 ) AS __sq WHERE __joined_row_num = 1 O
RDER BY __order', N'@0 int', @0 = 471

我正在寻找关于为什么会出现此错误的一些指导。感谢。

1 个答案:

答案 0 :(得分:0)

此行有问题

PARTITION BY [tProjects].*

我希望这里有一个特定的专栏。

我的PC上有类似的设置,但无法在rails控制台中复制您的问题。 activerecord-sqlserver-adapter (4.1.0) tiny_tds (0.6.2) rails (4.1.1) activerecord (4.1.1, 4.0.3)

这是我的输出:

rails c
Loading development environment (Rails 4.1.1)
2.1.0 :001 > require 'LvQaOrderService'
 => true
2.1.0 :002 > p = Product.where(id: 36860201)  
SQL (282.9ms)  USE [order_service]  
Product Load (313.2ms)  
EXEC sp_executesql N'SELECT [products].* FROM [products] WHERE [products].[id] = 36860201'
2.1.0 :003 > p.first.inventories
Inventory Load (343.9ms)  
EXEC sp_executesql N'SELECT DISTINCT [inventory].* FROM [inventory] INNER JOIN [product_inventory] ON [inventory].[id] = [product_inventory].[inventory_id] WHERE [product_inventory].[product_id] = @0', N'@0 bigint', @0 = 36860201`

这是我的设置:

#product.rb
class Product < LvQaOrderService
has_many :product_inventories
has_many :inventories, -> { uniq }, :through => :product_inventories
end

#product_inventory.rb
class ProductInventory < LvQaOrderService
self.table_name = "product_inventory" 

belongs_to :product
belongs_to :inventory
end

#inventory.rb
class Inventory < LvQaOrderService
self.table_name = "inventory" 

has_many :product_inventories
has_many :products, :through => :product_inventories
end