Ruby on rails searching arrays (Active record) - ruby-on-rails

I have a model with an array column. So I'm basically saving languages as an array to Postgres. For example, driver_language =["English", "Spanish", "French"]
In my Query, I want to select all vehicles where submitted_driver_language ["English", "Spanish"] is included in driver_language. Or at least one element of the submitted driver_language array is included in the driver_language column which is an array. How can I add that condition to the query below? Any help will be appreciated
Vehicle.where(:vehicle_type => vehicle_type, :active => true, :company_activated => true, :capacity => number_of_people.to_i..Float::INFINITY)

Use arel_table.
#vehicle = Vehicle.where(:vehicle_type => vehicle_type, :active => true, :company_activated => true, :capacity => number_of_people.to_i..Float::INFINITY)
avehicle = #vehicle.arel_table
#required_result = #vehicle.where(avehicle[:driver_language].matches('%#{"English", "Spanish"}%'))

What about a regex?
Vehicle.where('driver_language ~* ?', 'english|spanish')

Related

Can't access data in ActiveHash

I'm using the Gem active_hash https://github.com/zilkey/active_hash to create models for simple data that I don't want to create DB tables for.
For example, I have this model setup for FieldTypes:
class FieldType < ActiveHash::Base
self.data = [
{:id => 1, :name => "text", :friendly_name => "Text"},
{:id => 2, :name => "textarea", :friendly_ => "Text Area"},
{:id => 3, :name => "image", :friendly_ => "Image"},
]
end
And I'm trying to list these field types for a select:
def field_types_for_select
#FieldType.all.order('name asc').collect { |t| [t.friendly_name, t.name] }
FieldType.pluck(:friendly_name, :name)
end
But I get an error that order, collect or pluck are not defined.
How do I access this data? This works fine on other models, just not ActiveHash ones. According to the docs the model should work the same as ActiveRecord but I don't seem to be able to access it the same. FieldType.all works, but other methods do not.
Pluck isn't defined on ActiveHash::Base. It is defined on ActiveRecord::Relation::Calculations, and it's purpose is to produce a SQL select for the columns you specify. You will not be able to get it to work with ActiveHash.
You can, however, define your own pluck on your FieldType model.
def self.pluck(*columns)
data.map { |row| row.values_at(*columns) }
end
Or query the data directly:
FiledType.data.map { |row| row.values_at(:friendly_name, :name) }

Rails load some list ob objects to slow

it's my first question in stackoverflow.
In my application i have a real time section, to see the movements of the web. Its an online newspaper and ths section shows: new article, new comment, new vote, new debate.....all what is happening on the web.
I have this code:
def index
#objects = Article.find(:all, :conditions => { :created_at => (Time.now-48.hours)..(Time.now), :published => true })
#objects = #objects + Debate.find(:all, :conditions => { :created_at => (Time.now-48.hours)..(Time.now), :active => true })
#objects = #objects + Event.find(:all, :conditions => { :created_at => (Time.now-48.hours)..(Time.now), :active => true })
#objects = #objects + Comment.find(:all, :conditions => { :created_at => (Time.now-48.hours)..(Time.now), :active => true })
#objects = #objects + Vote.find(:all, :conditions => { :created_at => (Time.now-48.hours)..(Time.now) })
#objects.sort! {|x,z| x.created_at <=> z.created_at}
#objects.reverse!
end
I load all in the last 48 hours. I've been reading about caching in rails because I think that this isn't my solution.
What can I do to load this list more fast? Because now it takes 7...or 8 seconds...
Thanks for all :D
few notes:
find(:all) is deprecated. use where() instead.
instead of doing 5 db calls migrate them into one db call (create a sql query for that if needed).
make sure you index the dates columns in your tables.
don't sort sort and reverse. instead replace y <=> x so it will sort the way you need.
hope it helps..

Ruby on Rails 3: Updating join table, using 2 parameters?

I have a join table, which have 3 parameters. I want to update it, using a where-clause, something like this: (which obviously is not correct)
Grid.update(:page_id => #page_id,:thing_id => #thing_id,:number => #number ).where(:page_id => #page_id, :number => #number ).first
I need to find the record with mathing page_id and number, and then update the thing_id.
Thanks!
Jakob
Grid.where(:page_id => #page_id, :number => #number).first.
update_attributes(:page_id => ...,: thing_id => ..., :number => ...)

Ruby on Rails: testing if ActiveRecord results include a value

Afternoon,
Lets say I have gather a random selection of users:
User.find(:all, :limit => 10, :order => "rand()")
Now from these results, I want to see if the user with the ID of 3 was included in the results, what would be the best way of finding this out?
I thought about Array.include? but that seems to be a dead end for me.
Thanks
JP
users = User.find(:all, :limit => 10, :order => "rand()")
users.any? {|u| u.id == 3}
assert random_users.include?(User.find 3), "Not found!"
Active record objects are considered equal if they have equal ids. Array#include? respects the objects defined equality via the == method.
User.find(:all, :limit => 10, :order => "rand()").any? { |u| u.id == 3 }
This will save you from doing another find.

Counting and grouping at the same time

I have a Mail model with the following schema:
t.string "mail"
t.integer "country"
t.boolean "validated"
t.datetime "created_at"
t.datetime "updated_at"
And I want to find the top 5 countries in the database, so i go ahead and type
#top5 = Mail.find(:all,:group => 'country',:conditions => [ "validated = ?" , "t" ], :limit => 5 )
This will tell me the groups(i need an order by i dont know how to write)
#top5 = Mail.count(:all,:group => 'country',:conditions => [ "validated = ?" , "t" ], :limit => 5 )
This will tell me how many mails are in each group
Im wondering if i can group and count in just one go
Try:
Mail.count(:group => 'country', :conditions => ['validated = ?', 't'])
I'm not sure count accepts :limit though.
EDIT:
I think this is more readable:
Mail.count(:group => :country, :conditions => {:validated => true})
With Rails 3 you can simplify it further:
Mail.where(validated: true).count(group: :country)
You can order by fields in the group - in this case only :country would be valid:
Mail.where(validated: true)
.order(:country)
.count(group: :country)
You can also order by the count, using "count_all":
Mail.where(validated: true)
.order("count_all desc")
.count(group: :country)
You can also limit the number of groups returned. To do this you must call limit before calling count (because #count returns ActiveSupport::OrderedHash):
Mail.where(validated: true)
.order("count_all desc")
.limit(5)
.count(group: :country)
Updated syntax for Rails 4:
Mail.where(validated: true)
.group(:country)
.count
Mail.find(
:all,
:select => 'count(*) count, country',
:group => 'country',
:conditions => ['validated = ?', 't' ],
:order => 'count DESC',
:limit => 5)
This should give you records that have a country attribute and a count attribute.
I too had to group data with city name and showing count of how many rows are there for each city with specific condition. So this is how I did:
CityData.where(:status => 1).group(:city_name).count
Output of this was:
{:Mumbai => 10, :Dublin => 7, :SF => 9}

Resources