I'm wanting to use the Code by Zapier action to convert a string like this: "product 1, product 2, product 3" into an array like this [product 1, product 2, product 3] so the subsequent Zapier actions will run for as many times as there are values in the array. What code do I need to enable this?
You can use the str.split method to achieve that:
>>> products_str = "product 1, product 2, product 3"
>>> products = products_str.split(', ')
>>> products
['product 1', 'product 2', 'product 3']
Related
I have a simple Ruby on Rails app CookBook, with recipes. I have 2 tables (recipes and ingredients). One recipe has many ingredients.
I am trying to implement a simple search box so that I can filter recipes containing certain ingredients....
These are the tables:
create table recipes (id int, recipe_name varchar(100));
create table ingredients(id int, ingredient_name varchar(100), recipe_id int);
insert into recipes values
(1, 'my recipe 1'),
(2, 'my recipe 2');
(3, 'my recipe 3');
(4, 'my recipe 4');
insert into ingredients values
(1, 'Banana', 1),
(2, 'Milk', 1),
(3, 'Banana', 2),
(4, 'Milk', 2),
(5, '4 ½ teaspoons baking powder', 2);
(6, '1 ½ cups whole wheat flour', 4),
(7, 'Heavy Cream', 4);
(8, '⅓ cup packed brown sugar', 3),
(9, 'Milk', 3);
(10, '2 teaspoons packed brown sugar', 4);
Let's say I type in search box two ingredients, for example "banana" and "milk". Then I am expecting to get recipes with rows from ingredients table that contain those words...
This is the code in my recipes_controller I currently have:
def search
if params[:search].blank?
redirect_to recipes_path and return
else
#parameter = params[:search].downcase
#recipe_ids = Ingredient.search_ingredient(#parameter).pluck(:recipe_id)
#results = Recipe.where(id: #recipe_ids).paginate(page: params[:page], per_page: 26)
end
end
code in ingredient.rb:
class Ingredient < ApplicationRecord
belongs_to :recipe
include PgSearch::Model
pg_search_scope :search_ingredient,
against: { ingredient_name: 'A' },
using: {
tsearch: {
dictionary: 'english', tsvector_column: 'searchable'
}
}
end
The problem with this is that if I type 'Banana milk' in search box, I will not get anything in result set, because they are in separate rows in ingredients table, belonging to a recipe. In this case, I should get at least recipes with id 1 and 2, because they both have those ingredients
If I search for only one ingredient, like "milk" then I get all the recipes containing that ingredient.
How do I accomplish this?
Thank you in advance
I advise you to use any_word attribute, look at the documentation here - https://github.com/Casecommons/pg_search#any_word
pg_search_scope :search_ingredient,
against: { ingredient_name: 'A' },
using: {
tsearch: {
any_word: true,
dictionary: 'english',
tsvector_column: 'searchable'
}
}
I have a table DinnerItem with columns id, name, project_id, client_id, item_id and item_quantity.
I want to fetch data group_by item_id column and the value should only have the item_quantity column value in the format
{ item_id1 => [ {item_quantity from row1}, {item_quantity from row2}],
item_id2 => [ {item_quantity from row3}, {item_quantity from row4} ]
}
How can I achieve it in one single query?
OfferServiceModels::DinnerItem.all.select('item_id, item_quantity').group_by(&:item_id)
But this has the format
{1=>[#<DinnerItem id: nil, item_id: 1, item_quantity: nil>, #<DinnerItem id: nil, item_id: 1, item_quantity: {"50"=>30, "100"=>10}>], 4=>[#<DinnerItem id: nil, item_id: 4, item_quantity: {"100"=>5, "1000"=>2}>}
Something like this should do the job:
result = OfferServiceModels::DinnerItem
.pluck(:item_id, :item_quantity)
.group_by(&:shift)
.transform_values(&:flatten)
#=> {1 => [10, 20], 2 => [30, 40]}
# ^ item id ^^ ^^ item quantity
A step by step explanation:
# retrieve the item_id and item_quantity for each record
result = OfferServiceModels::DinnerItem.pluck(:item_id, :item_quantity)
#=> [[1, 10] [1, 20], [2, 30], [2, 40]]
# ^ item id ^^ item quantity
# group the records by item id, removing the item id from the array
result = result.group_by(&:shift)
#=> {1 => [[10], [20]], 2 => [[30], [40]]}
# ^ item id ^^ ^^ item quantity
# flatten the groups since we don't want double nested arrays
result = result.transform_values(&:flatten)
#=> {1 => [10, 20], 2 => [30, 40]}
# ^ item id ^^ ^^ item quantity
references:
pluck
group_by
shift
transform_values
flatten
You can keep the query and the grouping, but append as_json to the operation:
DinnerItem.select(:item_id, :item_quantity).group_by(&:item_id).as_json
# {"1"=>[{"id"=>nil, "item_id"=>1, "item_quantity"=>1}, {"id"=>nil, "item_id"=>1, "item_quantity"=>2}],
# "2"=>[{"id"=>nil, "item_id"=>2, "item_quantity"=>1}, {"id"=>nil, "item_id"=>2, "item_quantity"=>2}]}
Notice as_json will add the id of each row which will have a nil value.
I don't know that this is possible without transforming the value returned from the db. If you are able to transform this, the following should work to give you the desired format:
OfferServiceModels::DinnerItem.all.select('item_id, item_quantity').group_by(&:item_id)
.transform_values { |vals| vals.map(&:item_quantity) }
# => {"1"=>[nil,{"50"=>30, "100"=>10}],"4"=>...}
# or
OfferServiceModels::DinnerItem.all.select('item_id, item_quantity').group_by(&:item_id)
.transform_values { |vals| vals.map { |val| val.slice(:item_quantity) }
# => {"1"=>[{:item_quantity=>nil},:item_quantity=>{"50"=>30, "100"=>10}}],"4"=>...}
I'd argue there's nothing wrong with the output you're receiving straight from the db though. The data is there, so output the relevant field when needed: either through a transformation like above or when iterating through the data.
Hope this helps in some way, let me know :)
My goal is to write the query below in the cleanest, most efficient way possible and minimize hitting the DB. Appreciate any guidance in advance.
I have retrieved some records that belong to a user, like below:
english_shows = #user.shows.where(language: 'english')
Let's say the shows belong to different categories (using a foreign key), so it looks like below:
<ActiveRecord::Relation [
<Show id: 1, category_id: 1, title: 'Rick and Morty'>,
<Show id: 2, category_id: 2, title: 'Black Mirror'>,
<Show id: 3, category_id: 3, title: 'Stranger Things'>,
<Show id: 4, category_id: 3, title: 'Game of Thrones'>,
...
]
If I want to get the titles of the shows for each category, I know I can use select like this. The same thing can be done with where, but this would cause an additional DB call. ([Edit] Actually, both would hit the DB twice).
# Using select
cartoons = english_shows.select { |show| show.category_id == Category.find_by(name: 'cartoon').id}.pluck(:title)
# Using where
cartoons = english_shows.where(category_id: Category.find_by(name: 'cartoon').id)pluck(:title)
However, the select method would still result in multiple lines of long code (in my actual use case I have more category types). Is it cleaner to loop through the records like this (taken from this SO answer)?
cartoons, science_fiction, fantasy = [], [], []
#cartoon_id = Category.find_by(name: 'cartoon')
#science_fiction_id = Category.find_by(name: 'cartoon')
#fantasy_id = Category.find_by(name: 'cartoon')
english_shows.each do |show|
cartoons << show if show.category_id == #cartoon_id
science_fiction << show if show.category_id == #science_fiction_id
fantasy << show if show.category_id == #fantasy_id
end
Try this:
english_shows
.joins(:category)
.select('shows.*, categories.name as category')
.group_by(&:category)
I have an interest form which is used to add an interest to a user. The structure of the database is as follows:
Users - id ...
Interests - id ..
UsersMapInterests - user_id interest_id
So when a user selects an interest from the Interests table, it gets added to the UsersMapInterests table.
A query for user 1 would return something like {{user_id: 1, interest_id 3},{user_id: 1, interest_id 7},{user_id: 1, interest_id 25}}.
A query for user 22 would return {user_id: 22, interest_id 3},{user_id: 22, interest_id 3}
Now I would like to compare the results with each other.
I assume that using to_a and comparing them like this would be too much:
user1.each do |int1|
user22.each do |int2|
if int1.interest_id == int2.interest_id
count++
end
end
end
How else could I compare them?
You can just use the following line of code
(user1.interest_ids & user22.interest_ids).count
Explanation:
user1.interest_ids
#=> [3, 7, 25]
user22.interest_ids
#=> [3, 3]
[3, 7, 25] & [3, 3] # Returns common element from both arrays
#=> [3]
[3].count
#=> 1
I will do something like this:
user1_interest_ids = user1.map { |o| o[:interest_id] }
user22_interest_ids = user22.map { |o| o[:interest_id] }
count = (user1_interest_ids & user22_interest_ids).size
Let me describe with simple example.
I have a list of numbers:
ex: list = [ 3, 1, 2 ]
and I have a table in DB named Products which have 3 rows with product_id = 1, 2and 3.
Now I need to query Products sort by list values (3,1,2) so the result will be:
product_3
product_1
product_2
Query will be like:
product.sort(list) or product.order(list) or some other alternative pls
This should work for you:
list = [3, 1, 2]
Product.where(product_id: list).sort_by { |p| list.find_index(p.product_id) })