Test for "not equal" on array using Controller.where() possible? - ruby-on-rails

Is it possible to use the '.where()' controller method to select all db-elements that are not equal to an array consisting of ID numbers?
I can easily use the '.where()' controller method to select all db elements that are equal to a list of ID numbers stored in an array:
user_event_ids = current_user.event_items.pluck(:event_id)
#user_events = Event.where(id: user_match_ids)
But I can't seem to find a way to select all db-elements that have ID numbers which ar enot in the 'user_event_ids' array.
I've tried (with no luck):
#non_user_events = Event.where('user_id not in :arr', {arr: user_event_ids})
#non_user_events = Event.where(''user_id != ?', user_event_ids)
Both do not work and cancel with errors. Any help is appreciated!

This should be the correct syntax for what you are after:
Event.where('user_id NOT IN (?)', user_event_ids)

Given excluded_ids is an Array containing the IDs you want to exclude
If you are using Rails 4:
Event.where.not(user_id: excluded_ids)
If you are using Rails 3:
Event.where('user_id NOT IN (?)', user_event_ids)
If you are using Squeel
Event.where{user_id.not_in excluded_ids}

Here is another syntax:
Event.find(:all, :conditions => ['user_id not in (?)', user_event_ids])

Related

simple Or statement

I am trying to do a simple or statement in a controller
This generates one set of trips that I am interested in displaying and is working fine.
#trips = Trip.where(:userid => #friends)
However, i would like to add another set of trips; trips whose userid == current_user.id
#trips = Trip.where(:userid => current_user.id)
Trying to combine these two i tried...
#trips = Trip.where(:conditions => ['userid= ? OR userid=?', #friends, current_user.id])
Any idea where the bust is? Thanks in advance.
Simply pass an array to get the equivalent of the SQL WHERE ... IN clause.
Trip.where(userid: [#friends, current_user.id])
See the ActiveRecord Rails Guide, 2.3.3 Subset Conditions
Is #friends an array? ActiveRecord will convert your where statement into a SQL IN clause when you generate it with the hash syntax. When you build your OR statement in raw SQL, you need to do the IN manually.
#trips = Trip.where('userid IN ? OR userid = ?', #friends, current_user.id)
Also, your column is called userid ? Typicaly it would be called user_id - is this a typo or do you just have an abnormal database?

Ruby on Rails: Fetch database result and search through results

I have a set of IDs for a table called "brands". I want to fetch the name column for each record in the brand table without having to re-query the database using Brand.find(brand_id). Instead, is there a way to store the database results into a variable and query the variable?
Thanks.
if you already collected the records in a var #brands, you can use
name = #brands.find {|b| b.id == brand_id}.name
not a query
This will return an array of all Brands for a brand_id
Brand.find(:all, :conditions => ["brand_id = ?", brand_id])
For a collection of brand_ids
Brand.find(:all, :conditions => ["brand_id IN (?)", [brand_id1, brand_id2]])
HTH
You can write a method in your model brand.
def get_associated_brand
b = self.brand_id
brand = Brand.find(b).name
end
From your view just call this method so that in your view you ll get brand name instead of ID like
brand.get_associated_brand
instead of
brand.brand_id
About what was commented on #Harsh Gupta's answers, maybe
#filtered_brands = Brand.where(id: <some_id>)
Then you can access all info of each brand in a regular each loop.

IS NOT condition for rails instance variable

I have a hash with members of an appointment and try to create a MySQL query in my rails controller.
The users with the ids from the map command e.g. {1,3} should be excluded in the query.
So for example #appointment.members.map{|m| m.user_id} returns {1,3,5} and I'd like to find all other users but these.
#users = User.where( "id NOT IN (?)", #appointment.members.map{|m| m.user_id} )
I'm using Rails 3.2.9 so maybe my exclude statement is wrong cause I don't get any result out of this query. The problem can't be the map array - I already tested that.
Thanks in advance.
I think you just have a problem with the map method, try this:
#users = User.where( "id NOT IN (?)", #appointment.members.map(&:user_id) )
EDIT: removed the wrong syntax for future readers if any
I solved the problem with a new instance variable:
#members = #appointment.members.all
and then
#add_users = User.where( "id NOT IN (?)", #members.map(&:user_id) )
thanks for the support

How to get a single column's values into an array

Right now I'm doing something like this to select a single column of data:
points = Post.find_by_sql("select point from posts")
Then passing them to a method, I'd like my method to remain agnostic, and now have to call hash.point from within my method. How can I quickly convert this into an array and pass the data set to my method, or is there a better way?
In Rails 3.2 there is a pluck method for this
Just like this:
Person.pluck(:id) # SELECT people.id FROM people
Person.pluck(:role).uniq # unique roles from array of people
Person.distinct.pluck(:role) # SELECT DISTINCT role FROM people SQL
Person.where(:confirmed => true).limit(5).pluck(:id)
Difference between uniq and distinct
You should use the pluck method as #alony suggested. If you are stuck before Rails 3.2 you can use the ActiveRecord select method together with Array#map:
Post.select(:point).map(&:point)
#=> ["foo", "bar", "baz"]
before Ruby 1.9 you'd have to do .map{|x| x.title} though, because Symbol#to_proc (aliased by the unary & operator) is not defined in earlier versions of Ruby.
If you see the definition of select_values , then it using 'map(&:field_name)'
def select_values(arel, name = nil)
result = select_rows(to_sql(arel), name)
result.map { |v| v[0] }
end
The common and general Rails way to collect all the fields values in array is like :
points = Post.all(:select => 'point').map(&:point)
points = Post.all.collect {|p| p.point}

rails where() sql query on array

I'll explain this as best as possible. I have a query on user posts:
#selected_posts = Posts.where(:category => "Baseball")
I would like to write the following statement. Here it is in pseudo terms:
User.where(user has a post in #selected_posts)
Keep in mind that I have a many to many relationship setup so post.user is usable.
Any ideas?
/EDIT
#posts_matches = User.includes(#selected_posts).map{ |user|
[user.company_name, user.posts.count, user.username]
}.sort
Basically, I need the above to work so that it uses the users that HAVE posts in selected_posts and not EVERY user we have in our database.
Try this:
user.posts.where("posts.category = ?", "Baseball")
Edit 1:
user.posts.where("posts.id IN (?)", #selected_posts)
Edit 2:
User.select("users.company_name, count(posts.id) userpost_count, user.username").
joins(:posts).
where("posts.id IN (?)", #selected_posts).
order("users.company_name, userpost_count, user.username")
Just use the following:
User.find(#selected_posts.map(&:user_id).uniq)
This takes the user ids from all the selected posts, turns them into an array, and removes any duplicates. Passing an array to user will just find all the users with matching ids. Problem solved.
To combine this with what you showed in your question, you could write:
#posts_matches = User.find(#selected_posts.map(&:user_id).uniq).map{ |user|
[user.company_name, user.posts.size, user.username]
}
Use size to count a relation instead of count because Rails caches the size method and automatically won't look it up more than once. This is better for performance.
Not sure what you were trying to accomplish with Array#sort at the end of your query, but you could always do something like:
#users_with_posts_in_selected = User.find(#selected_posts.map(&:user_id).uniq).order('username DESC')
I don't understand your question but you can pass an array to the where method like this:
where(:id => #selected_posts.map(&:id))
and it will create a SQL query like WHERE id IN (1,2,3,4)
By virtue of your associations your selected posts already have the users:
#selected_posts = Posts.where("posts.category =?", "Baseball")
#users = #selected_posts.collect(&:user);
You'll probably want to remove duplicate users from #users.

Resources