Ahoy events queries in rails - sql

I started code rails recently and I need to figure out this problem.
%td
= Ahoy::Event.where(name: "viewed_brochure").where_properties(brochure_id: brochure.id).select(:session_id).uniq
This should find number of distinct values of session_id in properties field but it doesn't work.
This line returns these and similar errors
#<Ahoy::Event::ActiveRecord_Relation:0x007f52d9325130>
#<Ahoy::Event::ActiveRecord_Relation:0x007f52d9466508>
%td
= Ahoy::Event.select { |event| event.properties['session_id'] }.uniq.count
I tried this line but this time returns number of rows in table

You can try to group by jsonb key, in your case properties['session_id']
Ahoy::Event.group("properties -> 'session_id'").count
This will return the counts on which you can apply .size or you could do distinct.

Thank u so much #Anton I modify your solution and finally it works fine.
Here is the solution
%td
= Ahoy::Event.where_properties(brochure_id: brochure.id).group("properties -> 'session_id'").count.size

Related

Rails find by integer property fails

I have this query in a GET route:
#user = User.where("facebook_id = ?", params[:id].to_i).first
facebook_id is type bigint
and I am feeding it values that I know exist based on printing out all the properties in all my User models. The problem is this query only works on some numbers.
It works for these numbers:
1095512640500310
10155111451974992
10100608785176432
but not for these numbers
10154326172258840
10205871322198368
10153714225855256
Why does this query work for some numbers but not others?
UPDATE:
Here is a screenshot of a different query that prints out facebook_id values:
but this query: #user = User.find_by_facebook_id(10154326172258840)
returns nil for #user
UPDATE
I found that there is a discrepency between the value in the DB and the value that rails prints out. If I print out the facebook_id for this particular user in PG, I see this:
The last digit here is 1 while the last digit in the rails print out is 0.
Why would rails be printing out an incorrect value? Is it rounding for some reason?

using .where with .find

I am wondering how I can use where cause with the ActiveRecord find method.
Here is the code I am using:
Supplier.joins(:products).find(params[:id]).where('suppliers.permalink = ? AND variants.master = ?', params[:id], TRUE)
which gives me:
undefined method `where' for #<Supplier:0x007fe49b4eb330>
Supplier.joins(:products).find(params[:id]).where('suppliers.permalink = ? AND variants.master = ?', params[:id], TRUE)
What you're doing here is finding the first record with the id contained in params[:id], then trying to run a where statement on that single record. where only works when run against the model itself.
The confusing part here is that you are using params[:id] both for the primary key (find searches the id field) but then also comparing it to the permalink column in the where clause.
To explain the usage of both methods:
find will search for result(s) from the table, matching the argument you provide it to the id field. You can pass in multiple id's and this method is mostly used to select a row that you know exists, by id. Most commonly it is used with a single id and returns a single instance.
where is used to find all results from the table that match the clause and return a collection of records. You can then refine these results or select one, for example by using .first:
Supplier.joins(:products).where('suppliers.permalink = ? AND variants.master = ?', params[:permalink], true).first
(Note that you're using joins(:products) but then querying variants table. Is this incorrect?)
Supplier.joins(:products).where('suppliers.permalink = ? AND variants.master = ?', params[:id], TRUE).find(params[:id])

SQL injections in Rails 4 issue

I'm trying to learn about SQL injections and have tried to implement these, but when I put this code in my controller:
params[:username] = "johndoe') OR admin = 't' --"
#user_query = User.find(:first, :conditions => "username = '#{params[:username]}'")
I get the following error:
Couldn't find all Users with 'id': (first, {:conditions=>"username = 'johndoe') OR admin = 't' --'"}) (found 0 results, but was looking for 2)
I have created a User Model with the username "johndoe", but I am still getting no proper response. BTW I am using Rails 4.
You're using an ancient Rails syntax. Don't use
find(:first, :condition => <condition>) ...
Instead use
User.where(<condtion>).first
find accepts a list of IDs to lookup records for. You're giving it an ID of :first and an ID of condition: ..., which aren't going to match any records.
User.where(attr1: value, attr2: value2)
or for single items
User.find_by(attr1: value, attr2: value)
Bear in mind that while doing all this, it would be valuable to check what the actual sql statement is by adding "to_sql" to the end of the query method (From what I remember, find_by just does a LIMIT by 1)

RoR Search conditions comparing two columns

What I basically want to do is the following:
a = Assignment.all(:conditions => { :end_date < :start_date })
I only want to select those records on which the end_date is before the start_date.
I actually don't want ending up writing a
for each, push to array if end_date is earlier than start_date.
How can I achieve this in a pretty 'Railsy'-way?
Thank you in advance.
Edit:
I think the problem is comparing the values of both columns. (Allmost) every query is comparing a cell-value to an input-value.
This is a shot in the dark, but maybe one in the right direction ?
Haven't figured out a solution.
It's been a while here but nevertheless, you can just use the ArelTable method:
t = Assignment.arel_table
Assignment.where(t[:end_date].lt(t[:start_date]))
The condition predicates documentation: http://www.rubydoc.info/github/rails/arel/Arel/Predications
The ArelTable documentation: http://www.rubydoc.info/github/rails/arel/Arel/Table
And a good guide: http://jpospisil.com/2014/06/16/the-definitive-guide-to-arel-the-sql-manager-for-ruby.html
a = Assignment.all(:conditions => ["end_date < ?", :start_date ])
Check this: http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-all
I am assuming that you are using ActiveRecord
try
a = Assignment.where('regioassignments.end_date < regioassignments.start_date')
use the tablename followed by the EXACT COLUMNNAMES in the database, since ActiveRecord recognizes this and uses this as SQL directly.
That means the columnname for end_date is probably assignment_expected_end_date from what I figured from one of your comments.
adapted from this answer

Querying distinct with MongoMapper

How do I query distinct with MongoMapper? My query is:
subscribedToThread = Comment.where(:subscribe_thread => 1).all
But this will return many objects with the same user_id. I need to return just a distinct user_id. Is this possible?
I think you will need to drop down to the ruby driver in order to do this as I don't think you can do this with MongoMapper itself:
subscribedToThread = Comment.collection.distinct("user_id", {:subscribe_thread => 1})
Calling the collection method on a model returns the collection as would be provided by the Ruby driver directly so you can issue a distinct query using the syntax below:
collection.distinct(key, query = nil)
You can read more about it here
Yes, you can do so:
subscribedToThread = Comment.where(:subscribe_thread => 1).fields(:user_id).all.compact!.unique!
This will nil every field but user_id which you then uniq!,ie you remove all doubles and then compact! all nil
http://mongomapper.com/documentation/plugins/querying.html#fields
Try this
subscribedToThread = Comment.where(:subscribe_thread => 1).fields(:user_id).collect(&:user_id).uniq
It will show you list of uniq user_id