SQLite3::SQLException: no such column: parameters.user: - mysql

I am saving a list of followed users to the db and then trying to get the records where the current user is a part of that list but keep getting this exception.
SQLite3::SQLException: no such column: parameters.user: SELECT "activities".* FROM "activities" WHERE "parameters"."user" = 3
This is a record in the db
=> #<PublicActivity::Activity id: 107, trackable_id: 16, trackable_type: "Shout", owner_id: 1, owner_type: "User", key: "shout.shout", parameters: {:user=>[3]}, recipient_id: nil, recipient_type: nil, created_at: "2015-10-20 21:44:41", updated_at: "2015-10-20 21:44:41", read: false>
These are the queries I've tried that give me this. current_user.id = 3
PublicActivity::Activity.where({'parameters.user' => current_user.id})
PublicActivity::Activity.where(parameters: {user: current_user.id})
So. How do I get the records where the current user is a part of that list of users? Also, would the I be able to use the same query in Mysql?

Might seem like a silly question, but is the parameters column defined as a serialized column in the model? With adapters like MySQL and (I believe) SQLite you can't query serialized fields. So If it's something that you'd like to query, you need to save it separately from the serialized field.
That being said, with PostgreSQL and their rails adapter, you can query serialized fields.
You should check out this SO question and this anser

Related

Active Record: JSON Query

Inside my database model, I've got a json field which has the following structure:
json_field: {"data"=>{"key_1"=>"value1", "key_2"=>"value"} }
Trying to query this using select:
Model.select(:id, "json_field -> 'data'")
Model.select(:id, "json_field -> 'data' as data")
yields the array of objects, but without the json field selected.
#<ActiveRecord::Relation [#<Model id: 1, Model id: 2 ...>]
Thanks for any help.
This:
#<ActiveRecord::Relation [#<Model id: 1, Model id: 2 ...>]
is the result of calling inspect on the query and inspect will only display columns that the model knows about it. The model will query the table for the columns during startup so it will only know about columns that are actually in the table.
ActiveRecord creates column accessor methods on the fly using method_missing so it can create methods things in a query that aren't columns in the actual table.
So your data is there, you just have to ask for it by name, for example:
Model.select(:id, "json_field -> 'data' as data").map(&:data)
will give you the data values.

Sorting users in Rails based on values in array attribute of user model

I have a User model which has an array inside of it. This array is used to store points the user has scored in various activities. It basically looks like this:
<ActiveRecord::Relation [#<User id: 1, fullname: "Kaja Sunniva Edvardsen", points: [0, 4170, 3860, 2504, 2971, 3859, 4346]>, #<User id: 2, fullname: "Alexander Lie Sr.", points: [0, 3273, 3681, 2297, 2748, 4202, 3477]>]>
I want to sort all Users by the different values in the points array to be able to create ranking list for each of the different activities, points[0], points[1], etc...
Sorting by points[1] should return Kaja first, 4170>3273, sorting by points[6] should put Alexander first, 4202>3859
How do I do this?
As far as I know, MySQL does not have an integrated array type.
Assuming you have a model like this:
class User < ActiveRecord::Base
# ...
serialize :points, Array
# ...
end
You cannot sort with order queries, but you can try another solution (less efficient), handling the resources as an array:
User.all.sort { |user1, user2| user2.points[1] <=> user1.points[1] }
Which will return an array instead of an ActiveRecord query. Also, bear in mind that this code will not handle nil values (i.e. What if an user only have 2 elements in points?).

Rails query objects by key value of hash saved to column?

I have 2 objects, Visitors and Events. Visitors have multiple Events. An event stores parameters like this...
#<Event id: 5466, event_type: "Visit", visitor_token: "c26a6098-64bb-4652-9aa0-e41c214f42cb", contact_id: 657, data: {"url"=>"http://widget.powerpress.co/", "title"=>"Home (light) | Widget"}, created_at: "2015-12-17 14:51:53", updated_at: "2015-12-17 14:51:53", website_id: 2>
As you can see, there is a serialized text column called data that stores a hash with more data.
I need to find out if a visitor has visited a certain page, which would be very simple if the url parameter were it's own column, or if the hash were an hstore column, however it wasn't originally set up that way and it's a part of the saved hash.
Here's my attempted rails queries...
visitor.events.where("data -> url = :value", value: 'http://widget.powerpress.co/')
visitor.events.where("data like ?", "{'url' => 'http://widget.powerpress.co/'}")
visitor.events.where("data -> :key LIKE :value", :key => 'url', :value => "%http://widget.powerpress.co/%")
How does one properly query postgres to find objects that have a hash that contains a key with a specific value?
I suspect you're not looking for the right string. It should be "url"=>"http://widget.powerpress.co/", so:
visitor.events.where("data like ?", '%"url"=>"http://widget.powerpress.co/"%')
Check the right value directly in DB.
If you are storing hash in a text column, try following:
visitor.events.select{|ve| eval(ve.data)["url"] == "http://widget.powerpress.co/"}
Hope, it helps!
It worked for me.
visitor.events.select { |n| n.data && n.data['url'] == "http://widget.powerpress.co/"}

Ember many-to-many Ids are not included in JSON payload on post?

I have a meeting and a sales-rep models, The relation is ManyToMany.
The problem is, When I want to create a New meeting, and assign existing salesReps to it (They are already saved to the store), But The salesReps IDS are not included in The post action caused by model.save() (not even an empty array), To make it more clear, Here is what my code looks like:
meeting.coffee:
Meeting = DS.Model.extend
client: DS.belongsTo('client')
salesReps: DS.hasMany('sales-rep')
memo: DS.attr('string')
startDate: DS.attr('date')
duration: DS.attr()
sales-rep.coffee:
SalesRep = DS.Model.extend
meetings: DS.hasMany('meeting')
firstName: DS.attr('string')
lastName: DS.attr('string')
title: DS.attr('string')
meetings/new.coffee (the save action am using inside new meeting controller):
save: ->
meeting = #get('model')
meeting.set('client', #get('client'))
meeting.get('salesReps').pushObjects(#get('salesReps.content'))
meeting.save().then =>
#transitionToRoute 'meetings'
the JSON payload: ( POST http://localhost:4200/api/meetings)
meeting: {memo: null, start_date: null, duration: "00:15", client_id: null}
client_id: null
duration: "00:15"
memo: null
start_date: null
No matter what, There is no ANY trace of the salesReps ids in the payload!!
What I tried so far:
Setting the hasMany relation in the meeting model only.
Setting {async: true}, and then {async: false}, on both SalesRep, And
then on one of them
spending almost 2 days googling and reading all related posts in here
with no luck
Any Help/hints/Advice, Is highly appreciated
I will write the solution I found after endless reading and researching, I will write the full details, and trial/failure i've been through, Because no one, no one EVER should have to spend more than 3 days trying to fix something like that!!
I am using Ember-cli, So, there are a files/directories structure am following:
First attempt:
Trying all combinations of async: true, embedded true and what not.
Result, No luck
Second attempt:
in app/serializers/ I added the following serializer file:
meeting.coffee
`import DS from "ember-data"`
`import Ember from "ember"`
`import config from '../config/environment'`
get = Ember.get
serializer = DS.RESTSerializer.extend
serializeHasMany: (record, json, relationship) ->
rel_ids = get(record, relationship.key).map (rel) -> get(rel, 'id') || []
json["#{relationship.key.underscore().singularize()}_ids"] = rel_ids
json
`export default serializer`
result:
Adding this serializer, And I finally was able to send sales_rep_ids:[] array to the controller! and I could confirm that the server is saving the accociations as required.
But, When listing meetings, I was not able to list the associated salesReps, So, I checked the JSON am getting from the server, and it was correct (salesReps Ids were included!) But still not listed in Ember
Third Attempt:
After more reading and endless head-banging-against-the-wall, Changing ONE line fixed the problem!:
in app/serializers/meeting.coffee
change serializer = DS.RESTSerializer.extend to
serializer = DS.ActiveModelSerializer.extend
And Voila! Saved to the back-end, And listed correctley as association in ember!
This solution is a result of 3+ of constant headache, Am posting it here hopefully it might be helpful to someone facing the same problem, I can't claim that it's my own solution, but, It's the result of reading many people's code.
am not sure if it's the Ember way to do so, So, Any suggestions, Improvements Ideas and thought are welcome.

Recursive as_array for One-to-many relationships with Kohana 3 ORM

To begin with I'd like to say I know how to create ugly solutions for my problem. I am searching good solutions and best practices :)
How do I create deep hierarchial arrays (to json_encode later) from Kohana 3 ORM objects including related objects where the relation type is one-to-many?
The problem is that the ORM->as_array() method does work recursively for the "has one" and "belongs to" relationships but will stop and force you to use ->find_all() manually when you encounter a "has many" relationship.
Say I am creating a JSON API REST server using Kohana 3 and the built in ORM.
When someone looks at this URL: www.example.com/api/user?id=5
They will be served a JSON object for the user where id=5.
These are the orm-models and the relations:
User belongs to a Country
User has many Messages.
Message belongs to a Category
I would like this to work:
echo json_encode(
ORM::factory('user', 5)
->with('country')
->with('messages')
->with('messages:category')
->find()
->as_array()
);
and give me output like this:
{
name: "John"
age: 54,
country_id: 5,
country: {
name: 'Sweden',
code: 'SE'
},
messages: {
{
content: 'Lorem ipsum dolor...',
category_id: 1,
category: {...}
},
{
content: 'Sit amet elit...',
category_id: 2,
category: {...}
},
{
content: 'Consectetur ipsum dolor...',
category_id: 3,
category: {...}
}
}
}
BUT THAT WONT WORK.
This is all you would get:
{
name: "John"
age: 54,
country_id: 5,
country: {
name: 'Sweden',
code: 'SE'
}
}
Has someone forked or extended the Kohana 3 ORM to support this kind functionality?
Does someone know of any good Kohana 3 api module that takes care of this issue for you somehow?
As far as I know, there is no way to do this using only the ORM. This is the case for two reasons:
If a message has a relation for category, that usually means that category has a corresponding relation for the messages in the category. If you want to get the message "in full" - i.e. including its category - let's say that you also want to get the category "in full" - i.e. including its messages. This is obviously a very bad idea, as you could very easily design yourself into an infinite loop. In other words, if there was a magic "recurse all relations" capability, how would it know when to stop recursing?
All that the ORM is doing behind the scenes when you call find() is building a SQL query that returns a row of data from the database. However, what you are trying to do is too complicated for a single query that returns a single row. (There is a way to retrieve multiple rows as one row with comma-separated values in each field using MySQL's GROUP_CONCAT function, but I guarantee you that it is not worth the trouble.)
For both of these reasons, the ORM's with() method only works on belongs_to (in your case, the user's country and the message's category).
One way to do this query is to break it up into three steps, like this:
// Step 1: Get the user
$user = ORM::factory('user', 5)
->with('country')
->find();
// Step 2: Get the messages
$user->messages
->with('category')
->find_all();
// Step 3: Make user and the messages into arrays.
// User is easy, but messages are a little harder
// because they need to turn
// from "an object containing an array of objects"
// into "an array of arrays."
$user_arr = $user->as_array();
$fixer = function($obj)
{
return $obj->as_array();
};
$user_arr['messages'] = array_map($fixer, $user->messages->as_array());
// Now you can output it
echo json_encode($user_arr);