简体   繁体   中英

How to find records where a column value = [given array] in rails

Setup: Rails + Postgres.

I have table A with columns

id: int, name: string, address: string, s_array: varchar[], i_array: int[], created_at: datetime)

For a row, i need to find all the rows which have similar values. In rails, then query would look like

row = A.find(1) # any random row
ignore_columns = %w[id created_at]
A.where(row.attributes.except(*ignore_columns))

This works if we don't have column with array type. How to find all records where a value = [given array]?

Edit: To be clear, I want to pass multiple columns in where clause where some columns are of type array. For values in where clause, I am passing hash (row.attributes.except(*ignore_columns) is a hash)

Edit 2: Example:

Lets say I have a Query table

Query(id: Int, name: String, terms: varchar[], filters: int[], city: string, created_at: datetime)

id = primary key/integer
terms = array of string
filters = array of integer (it is an enum and we can select multiple which is saved as array)
other fields = self explanatory

Suppose I have following rows

(1, "query1", ["john"], [0], "wall", <some_date>)
(1, "query2", ["eddard", "arya"], [0, 1], "Winterfell", <some_date>)
(1, "query3", ["sansa", "arya"], [1, 2], "Winterfell", <some_date>)

Now when I add new row

row = ActiveRecord of (1, "query4", ["eddard", "arya"], [0, 1], "Winterfell", <some_date>)

What I want is to search already existing records like this

ignore_attributes = %w[id name created_at]
Query.where(row.attributes.except(*ignore_attributes))

This query should return already existing query3 so that I won't need to add new row with name query4.

The problem is that because some column types are of array type, then passing them as hash/conditions in where clause is not working.

Your query in rails look like below

row = A.find(1)

where_clauses = row.attributes.reject{|k,v| %[id, created_at].include?(k)}

A.where(where_clauses)

Try this example:-

    ##black list of attributes
   ignore_attributes = %w[id name created_at]

   MyModel.where(active: true).select(MyModel.attribute_names - ignore_attributes)

   =====The above query can also be chained as:- =====

   ##you have a city column too
    MyModel.where(active: true).select(MyModel.attribute_names - ignore_attributes).where.not(:city=>["Sydney","London"])

If you need this a permanent fix,you can add this line in your model.rb file. but its dangerous.

self.ignored_columns = %w(id name created_at)

Hope it helps :)

将find_by用于find_all_by,它将返回所有匹配的结果。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM