rails find - condition on array of db-fields - ruby-on-rails

I am stuck and I guess it is a syntax thing I just don't get:
It's a one(category)_to_many(product) relationship.
In my category model I have the columns pick1, pick2, pick3, pick4, pick5.
Each of those holds the id of a product.
In my category_controller I want to retrieve those in a find:
#productpicks = Product.find(:all, :conditions =>
['online = ? and category_id IN (?)', true,
[#category.pick1, #category.pick2, #category.pick3, #category.pick4, #category.pick5]])
... and iterate over them in the view like this:
do something
But there is nothing to be found in that array ...
Does anyone have an idea what I am doing wrong?
Thanks for helping!
Val

Shouldn't it be:
#productpicks = Product.find(
:all,
:conditions => [
'online = ? and id IN (?)',
true, [
#category.pick1,
#category.pick2,
#category.pick3,
#category.pick4,
#category.pick5
]
]
)
Replacing category_id with id in the where clause?
As pick1-5 hold product ids, and you are trying to find those specific products.

Related

can you force ActiveRecord find to include nil when associated record not found

Is there a way to force :include in ActiveRecord find to output nil in results where conditions are not met?
For example if I have classes: Parent and Children. Parent has many childrens and I do something like this:
children_ids = [1,2,3]
my_parent = Parent.find(:all,
:include => :children,
:conditions => ['parent.id = 1 AND children.id IN (?)', children_ids])
Assuming that I have only childrens with id 2 and 3 statement:
my_parent.children
will return array with two childrens. But I would like to know which one they are (second and third in my children_ids array). So is it possible for :include to input nil for child that I'm missing?
If this description is too confiusing then let me know and I will try to present it better.
If you want to find out what records were missing, you can do it in rubyland by processing retrieved records.
retrieved_ids = my_parent.children.map(&:id)
unretrieved_ids = children_ids - retrieved_ids

checking if params exists in rails

This is what I'd like to do:
I have this piece of code:
customer = Customer.find(:first, :conditions => {:siteId => params[:siteId], :customerCode => params[:id]})
If :customerCode is null, I'd like to use :temporaryCode instead. But I don't know how.
Thanks in advance.
customer = Customer.find_by_siteid_and_customercode params[:siteId], params[:id]
customer ||= Customer.find_by_siteid_and_temporarycode params[:siteId], params[:id]
making use of finders is most safer, cleaner
I'm pretty sure you want to use COALESCE inside the database:
customer = Customer.where(:siteId => params[:siteId])
.where('coalesce(customercode, temporarycode) = ?', params[:id])
.first
The SQL COALESCE function returns the first of its arguments that isn't NULL. For example:
coalesce(column1, column2)
gives you column1 if column1 isn't NULL and column2 if column1 is NULL.
If you're using Rails2 then something like this should work:
Customer.find(:first, :conditions => [
'siteid = ? and coalesce(customercode, temporarycode) = ?',
params[:siteId], params[:id]
])

How to make a join between 2 tables in Rails that returns the data of both tables

I'm trying to join two tables: Rooms and Room_Types (which have a relationship already). The thing is, I'm trying to do something like:
room = Room.all :conditions => ['rooms.id = ?', #room_id],
:joins => :room_type
room.to_json
..and this JSON is being sent to my view.
However, the JSON is only showing the fields of the Room table and is not including the Room_Type fields, and I need both tables' fields in this JSON. How can I accomplish this?
:joins only performs a JOIN. As in SQL, this does not add the JOINed table's columns to the results. If you want to do that you should use :include instead:
rooms = Room.all :conditions => [ 'rooms.id = ?', #room_id ],
:include => :room_type
rooms.to_json
Or, in Rails 3 parlance:
rooms = Room.where(:id => #room_id).include(:room_type).all
rooms.to_json
try
Room.joins(:room_type).where(:id => #room_id).select('room_types.foo as foo, room_types.bar as bar')

Search with multiple columns in Rails

While using the command:
#items = Item.find(:all,:order => 'name', :conditions => ["name LIKE ?", "%#{params[:key]}%"])
This works perfectly fine, but the search is only based on just a column. How do i make it search other columns, like description, category?
I am assuming you are using Rails 2, since you are using ActiveRecord 2 style syntax. You can just add the other columns as additional conditions, like this:
key = "%#{params[:key]}%"
#items = Item.find(:all, :conditions => [
'name LIKE ? OR description LIKE ? OR category LIKE ?',
key, key, key
], :order => 'name')
For reference, here's how you would do it in Rails 3:
key = "%#{params[:key]}%"
#items = Item.where('name LIKE ? OR description LIKE ? OR category LIKE ?', key, key, key).order(:name)
What if you have 15 columns to search then you will repeat key 15 times. Instead of repeating key 15 times in query you can write like this:
key = "%#{params[:key]}%"
#items = Item.where('name LIKE :search OR description LIKE :search OR category LIKE :search', search: key).order(:name)
It will give you same result.
Thanks

How to simulate a NOT IN SQL condition in the following case

I'm using Ruby on Rails 2.3.8 and I would like to get all the #products that haven't been already added to the listed_products array.
For example, let's say I've got the following code:
listed_products = ['1', '2', '3', '4', '5']
#Then, I would like to do something like SELECT * FROM products where id not in
#(listed_products), and save the result in #products
I know the above SQL syntax won't work, but I just wanted to give you guys the idea of what I want to achieve.
Is there a "rails way" for doing this?
Thanks in advance!
Yes, you can do the following (Rails 2.3.x):
listed_products = [1,2,3,4,5]
Product.find(:all, :conditions => ["id NOT IN (?)", listed_products])
Or this in Rails 3.0.x:
listed_products = [1,2,3,4,5]
Product.where("id NOT IN (?)", listed_products)
Pan's answer is correct, but you can also use scopes in 2.3.8, which lets you chain with other scopes for the class:
class Product
...
named_scope :excluding_ids, lambda { |*ids|
if ids.count==0 then
{}
else
{:conditions => ["id NOT IN (?)",ids]}
end
}
...
end
Then you can chain with other scopes in your class. Say you have a scope named :active. Then you can do:
Products.active.excluding_ids(*listed_products).find :all, ... more conditions ...
and it would be independent of order of the scopes:
Products.excluding_ids(*listed_products).active.find :all, ..
The best I can think of is:
SELECT * FROM products where id not = '1' and id not = '2' (etc...)
Not what you're after I'm sure, but it may be the only way!

Resources