Actual behavior
It seems that limit() doesn't add to the generated subquery which actually is a Model::ActiveRecord_Relation, instead tries an execution which throws the error:
ActiveRecord::StatementInvalid Exception table doesn't exists
Code and how to get the issue
class Doc < ApplicationRecord
self.table_name = "D_docs"
has_many :doc_dirs
has_many :dirs, through: :doc_dirs
default_scope -> { where(inactive: false, is_version_1: true)}
scope :doc_collection, -> do
str_sql = "
(
SELECT [D_docs].[fileType], [D_docs].[inactive], [D_docs].[isVisible]
FROM [D_docs]
) [D_docs]
"
doc_collec = Doc.from(str_sql).limit(10)
# byebug
doc_collec
end
end
On rails console if you add a debug between
doc_collec = Doc.from(str_sql).limit(10) and doc_collec
running doc_collec.to_sql you will get:
ActiveRecord::StatementInvalid Exception: Table '( SELECT [D_docs].[fileType], [D_docs].[inactive], [D_docs].[isVisible] FROM [D_docs] ) [D_docs]' doesn't exist
it should be noted that Doc.from(str_sql).to_sql is giving: SELECT [D_docs].* FROM ( SELECT [D_docs].[fileType], [D_docs].[inactive], [D_docs].[isVisible] FROM [D_docs] ) [D_docs]
A correct and without errors of Doc.from(str_sql).limit(10) is working on older rails versions (6.1.7) and SQL Server adapter version 6.x.x successfully generating the query:
SELECT [D_docs].* FROM ( SELECT [D_docs].[fileType], [D_docs].[inactive], [D_docs].[isVisible] FROM [D_docs] ) [D_docs] OFFSET 0 FETCH NEXT 10 ROWS ONLY
Also Doc.from(str_sql).order(:pkid) works as expected
The versions:
- Rails version:
7.1.2 - SQL Server adapter version:
7.1.0 - TinyTDS version:
2.1.5
UPDATE
Thanks to @engineersmnky
After changing doc_collec = Doc.from(str_sql).limit(10) to
doc_collec = Doc.from(Arel::Nodes::TableAlias.new(Arel::Nodes::TableAlias.new(Doc.select(:fileType,:inactive,:isVisible).arel, self.table_name))).limit(10)
I'm getting:
SELECT [D_docs].* FROM (SELECT [D_docs].[fileType], [D_docs].[inactive], [D_docs].[isVisible] FROM [D_docs]) [D_docs] ORDER BY [D_docs].[docName] ORDER BY [D_docs][pkid] OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY
which works (have to change the query); now I'd like to prevent the order by [D_docs].[pkid] if is possible, the reason not pkid is needed bc I'm planning to add an union query, how can I do it?
Based on your post I am making the following assumption (as it is the only way that SQL code be generated as stated)
That being said we can construct your desired functionality as follows:
This will result in:
Note by excluding the selection of the primary key you will not be able to relate this data to other associations such as
doc_dirs, please ensure this is your explicit intention or simply addpkidto the select list above.Discourse
Your question is unclear as to: (Answered in comments)
[D_docs]is, since it seems like it that table does not exist?[D_docs]?