-
-
Notifications
You must be signed in to change notification settings - Fork 638
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Accessible by strategy: Exists subquery #691
Changes from 1 commit
bd4fb38
f181dc5
f77a096
704176a
fc3c88d
efb09cd
b4536fd
64f37c3
be79997
e70c734
279fdb5
f18c5aa
493af4c
70b983d
f101181
8bb0a9b
bf86cd6
7373d0b
dd26042
ec37dbd
45a4416
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,17 +21,57 @@ def self.matches_condition?(subject, name, value) | |
|
||
private | ||
|
||
delegate :connection, :quoted_primary_key, to: :@model_class | ||
delegate :quote_table_name, to: :connection | ||
|
||
def build_joins_relation(relation, *where_conditions) | ||
case CanCan.accessible_by_strategy | ||
when :subquery | ||
inner = @model_class.unscoped do | ||
@model_class.left_joins(joins).where(*where_conditions) | ||
end | ||
@model_class.where(@model_class.primary_key => inner) | ||
|
||
build_joins_relation_subquery(where_conditions) | ||
when :left_join | ||
relation.left_joins(joins).distinct | ||
when :double_exist_subquery | ||
build_joins_relation_double_exist_subquery(where_conditions) | ||
end | ||
end | ||
|
||
def build_joins_relation_subquery(where_conditions) | ||
inner = @model_class.unscoped do | ||
@model_class.left_joins(joins).where(*where_conditions) | ||
end | ||
@model_class.where(@model_class.primary_key => inner) | ||
end | ||
|
||
def build_joins_relation_double_exist_subquery(where_conditions) | ||
@model_class.where("EXISTS (#{double_exists_query_sql(where_conditions)})") | ||
end | ||
|
||
def double_exists_inner_query(where_conditions) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure the code has gotten less abstract having to use this many helper methods, but I couldn't otherwise find a way around the Rubocop complexity offences :'-( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I honestly might get rid of rubocop and switch to standard soon :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Personally I feel that Rubocop has forced me to make the code more abstract than it had to be here :-) |
||
@model_class | ||
.unscoped | ||
.select('1') | ||
.left_joins(joins) | ||
.where(*where_conditions) | ||
.where( | ||
"#{quoted_table_name}.#{quoted_primary_key} = " \ | ||
"#{quoted_aliased_table_name}.#{quoted_primary_key}" | ||
) | ||
end | ||
|
||
def double_exists_query_sql(where_conditions) | ||
'SELECT 1 ' \ | ||
"FROM #{quoted_table_name} AS #{quoted_aliased_table_name} " \ | ||
'WHERE ' \ | ||
"#{quoted_aliased_table_name}.#{quoted_primary_key} = #{quoted_table_name}.#{quoted_primary_key} AND " \ | ||
"EXISTS (#{double_exists_inner_query(where_conditions).to_sql})" | ||
end | ||
|
||
def quoted_aliased_table_name | ||
@quoted_aliased_table_name ||= quote_table_name('aliased_table') | ||
end | ||
|
||
def quoted_table_name | ||
@quoted_table_name ||= quote_table_name(@model_class.table_name) | ||
end | ||
|
||
def sanitize_sql(conditions) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This refactor was needed to deal with Rubocop complexity offences.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should probably, at some point, extract these strategies
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@coorasse I have extracted all strategies as separate classes (also to solve Rubocop complexity issues). What do you think?