Convert simple string into array - zapier

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

Rails + PostgreSQL - Multiple Keyword Search using Full Text Search

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'
}
}

Rails group by column and select column

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 :)

Is it better to use select or loop through an array of records in Rails?

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)

Compare 2 ActiveRecord Relations rails

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

Rails - Query table with array of IDs and order based on the array

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) })

Resources