Skip to content
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

Add table name to search query #830

Merged
merged 2 commits into from
Apr 28, 2017
Merged

Add table name to search query #830

merged 2 commits into from
Apr 28, 2017

Conversation

klaseskilson
Copy link
Contributor

Hi! As always, thank you for a great gem. Ran into a problem with a pretty straightforward fix. Hit me with your feedback! 👍

Problem

When default scopes with joins are used, the generated search query can lead to ambiguity. For instance, the column id may exist in two tables, which will lead to a SQL error when it is impossible to decide which table to use.

Solution

Add resource_class's table_name to the generated search query. This ensures that the generated query produces the format table_name.id instead of id in the where clause generated for the search.

Problem: When default scopes with joins are used, the generated
search query can lead to ambiguity. For instance, the column
`id` may exist in two tables, which will lead to a SQL error when it is
impossible to decide which table to use.

Solution: Add `resource_class`'s `table_name` to the generated search
query. This ensures that the generated query produces the format
`table_name.id` instead of `id` in the where clause generated for the
search.
@@ -19,9 +19,10 @@ def run
private

delegate :resource_class, to: :resolver
delegate :table_name, to: :resource_class
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kind of thinking this was a bad idea, and that using resource_class.table_name might be a bit more clear. let me know what you think!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use resource_class.table_name because you aren't' frequently changing data types as you chain and you don't expect resource_class to become possibly nil at any point.


def query
search_attributes.map { |attr| "lower(#{attr}) LIKE ?" }.join(" OR ")
search_attributes.map { |attr| "lower(#{table_name}.#{attr}) LIKE ?" }.join(" OR ")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@klaseskilson someone just opened a PR showing that this code doesn't align with the SQL standard in #829. Are you able to quote the table name and, just to leave things in better shape than they were before, the column name as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing, on it.

resolver = double(resource_class: User, dashboard_class: MockDashboard)
search = Administrate::Search.new(resolver, "test")
expected_query = [
"lower(name) LIKE ? OR lower(email) LIKE ?",
"lower(users.name) LIKE ? OR lower(users.email) LIKE ?",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SQL should probably be:

lower("users"."name") LIKE ? OR lower("users"."email") LIKE ?

@@ -19,9 +19,10 @@ def run
private

delegate :resource_class, to: :resolver
delegate :table_name, to: :resource_class
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use resource_class.table_name because you aren't' frequently changing data types as you chain and you don't expect resource_class to become possibly nil at any point.

@BenMorganIO BenMorganIO self-requested a review April 12, 2017 16:38
Copy link
Collaborator

@BenMorganIO BenMorganIO left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's get that quoting in for the table name and column and refactor the delegate.

@klaseskilson
Copy link
Contributor Author

@BenMorganIO Pushed 63d01d0 with quoting. 👍

@BenMorganIO
Copy link
Collaborator

Note: fixes #829

@nickcharlton
Copy link
Member

Looks great! Thanks!

@nickcharlton nickcharlton merged commit 6459a60 into thoughtbot:master Apr 28, 2017
@nickcharlton nickcharlton added this to the v0.6.0 milestone Apr 29, 2017
iarie pushed a commit to iarie/administrate that referenced this pull request Jun 17, 2017
* Add table name to search query

Problem: When default scopes with joins are used, the generated
search query can lead to ambiguity. For instance, the column
`id` may exist in two tables, which will lead to a SQL error when it is
impossible to decide which table to use.

Solution: Add `resource_class`'s `table_name` to the generated search
query. This ensures that the generated query produces the format
`table_name.id` instead of `id` in the where clause generated for the
search.

* Quote table and column name in search

Closes thoughtbot#829
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants