Find hash attribute value on active record rails - ruby-on-rails

I am developing the application with Ruby on Rail. As in my current project I have an active record model as an example below :
<Site id: 6241, collection_id: 7, name: "ABC", properties: {"31"=>20}>
<Site id: 6242, collection_id: 7, name: "ABC", properties: {"10"=>20}>
<Site id: 6243, collection_id: 7, name: "ABC", properties: {"11"=>30}>
However, I want to find the site which has the properties with the key '31' and value 20, but I cannot find the way to compare this hash attribute. So is there any way you could suggest me?

Also assuming your column type is an hstore, you can just:
Site.where(properties: { key: "value" })

If column type hstore and db postgres you can search by this query:
Site.where("properties #> hstore(?, ?)", 'key', 'value')

I also use mysql and this will work:
Site.where(properties: {"31"=>20}.to_yaml)

Related

How do I define products with only specific property tags (Spree, Rails)

I've got a custom Spree app. I need to query Spree::Products that have the associated Spree::Property
I have a 'property' with the name "Rating" on only certain products, but I can't query those products correctly. What I have now is:
Spree::Product.joins(:properties).where(:property_name.downcase == "rating")
but that just pulls all the products that have any :properties associated with them at all.
Spree::Property -
Spree::Property(id: integer, name: string, presentation: string, created_at: datetime, updated_at: datetime)
Just tested on Spree 3.1. You can do that from Product or Property model.
Spree::Product.joins(:properties).where(spree_properties: {name: "rating"})
or
Spree::Property.where(name: "rating").first.products
*You have to modify the code to use downcase string.

Insert JSON file into Postgres through Rails

I'm not familiar on how to handle inserting JSON in a Postgres DB in Rails. I saw you can declare a json column type in rails.
I now want to run the command Users.new("Bob", bob) but get the error:
ArgumentError: wrong number of arguments (given 2, expected 0..1)
bob = {
name: "Bob",
occupation: "Coder",
pets: [
name: "Foo",
type: "dog"
]
}
class CreateUsers < ActiveRecord::Migration[5.1]
def change
create_table :users do |t|
t.string :name
t.json :data
end
end
end
In Rails console, I also double checked my table to make sure it's what I expected. So not sure what I'm doing wrong.
User(id: integer, name: string, data: json)
You need to specify the names of the columns. Try this:
Users.new(name: "Bob", data: bob)
I forgot to add the name of the columns I'm passing my values to.
Users.new("Bob", bob)
becomes
Users.new(name: "Bob", data: bob)

Intersection of 2 arrays of hashes by hash value (such as id)

In my rails app, I have a user model and a linkedin_connection model. Linkedin_connection belongs to user and user has_many linkedin_connections.
What's the best way to create a crossover array of connections between user1 and user2?
============== EDIT ============== EDIT ============== EDIT ==============
I realized that this is sort of a different problem than I originally thought. I have 2 arrays of hashes. Each hash has an id element. How can I find the intersection of two hashes by their ids?
Example
user1.linkedin_connections => [{id: "123xyz", name: "John Doe"}, {id: "789abc", name: "Alexander Supertramp"}]
user2.linkedin_connections => [{id: "456ijk", name: "Darth Vader"}, {id: "123xyz", name: "John Doe"}]
cross_connections => [{id: "123xyz", name: "John Doe"}]
How can I calculate "cross_connections?"
Thanks!
What you want is the intersection of the two arrays. In ruby, that's easy, using the & operator:
crossover_connections = user1.linkedin_connections.to_a & user2.linkedin_connections.to_a

Ordering with Rails query with Hstore

I have a model Post
#<Post id: 121978, created_at: "2014-05-02 18:11:15", updated_at: "2014-05-02 18:11:15", data: {"hi"=>"1", "hello"=>"9999"}, review_id: nil>
And I'd like to sort them based on hello within the hstore datatype column data
I made this query:
Post.order("data -> 'hello'")
Which works but since Hstore is in string, I have 780, 78, 77, ... as an output.
I think you can cast the value as an integer before being processed by order. I'm not that familiar with Hstore, but here are some examples of how you might try to do that:
Post.order("CAST(data -> 'hello' AS INT)")
Post.order("CONVERT(INT, data -> 'hello')")
Post.order("(data -> 'hello') * 1")

Rails active record query, serialized array

Suppose I have Users data that store array of pet in String datatype
[
#<User id: 1, name: "John", pets: "---\n- cat\n- dog\n- bunny\n- ''\n">,
#<User id: 2, name: "Pete", pets: "---\n- dog\n- bunny\n- ''\n">,
#<User id: 3, name: "Jack", pets: "---\n- cat\n- ''\n">,
#<User id: 4, name: "Kurt", pets: "---\n- cat\n- bunny\n- ''\n">
]
Can i get all users that has a cat? Maybe something like User.find_all_by... or User.where(....) or anything that return as a relation? So i can order with active record query.
I know i can get all users that has a cat with
User.all.select{|s| YAML.load(s.pets).include?'cat'}
, but it convert to array that cannot be ordered with active record query.
thx for helping.
You could use simple SQL to see if 'cat' shows up in the serialized column.
User.where('pets LIKE "%cat%"').all
You need to normalize your data, add Pet model and set has_and_belongs_to_many association between theese models.

Resources