How to use Magentor gem - ruby

I am trying to use the Magentor gem. The documentation is very weak. I succeeded in calling Magento::Category.info(1).
But I failed to call Magento::Category.create(args).
The method definition is like the following.
# catalog_category.create
# Create new category and return its id.
#
# Return: int
#
# Arguments:
#
# int $parentId - ID of parent category
# array $categoryData - category data ( array(’attribute_code’⇒‘attribute_value’ )
# mixed $storeView - store view ID or code (optional)
def create(attributes)
id = commit("create", attributes)
record = new(attributes)
record.id = id
record
end
Here's what I tried.(parent id is 1)
args = [1, {:name => 'Cars', :description => 'Great Cars', :is_active => '1', :url_key => 'cars'}]
category_id = Magento::Category.create(args)
exception: 1 -> SQLSTATE[21000]: Cardinality violation: 1241 Operand should contain 1 column(s)
Can anybody provide an example of calling the method?

I contacted the gem developer and got the following reply. A nice guy.
Hi Sam,
Sorry about the sparse documentation. We had created this library very quickly and only used a small subset of the api in the project we were working on.
It looks like the call for create in the library does not pass through data correctly. Here is a workaround:
parent_id = 1
attributes = {
:url_key=>"cars",
:description=>"Great Cars",
:name=>"Cars",
:is_active=>"1",
:available_sort_by => "Name",
:default_sort_by => "Name",
:include_in_menu => '1'
}
category_id = Magento::Category.commit("create", parent_id, attributes)
I'll also commit a fix to github that takes the parent_id correctly.
Thanks,
-preston

Related

Take one and skip other duplicate item in a child table

I have a list of Items and every item have some list, Now I wants to select Distinct items of child. I have tried like below but it's not working.
var items = await _context.Items.
Include(i => i.Tags.Distinct()).
Include(i => i.Comments).
OrderBy(i => i.Title).ToListAsync();
//Tag items
TagId - tag
------------------
1 --- A
2 --- B
3 --- B
4 --- C
5 --- D
6 --- D
7 --- F
//Expected Result
Item.Tags -> [A,B,C,D,F]
how can I do this in EF Core? Thanks.
You can use the MoreLinq library to get DistinctBy or write your own using this post.
Then use this:
var items = await _context.Items.
Include(i => i.Tags).
Include(i => i.Comments).
OrderBy(i => i.Title).
DistinctBy(d => d.Tags.tag).
ToListAsync();
You want to get distinct records based on one column; so that should do it.
Apparently you have a table of Items, where every Item has zero or more Tags. Furthermore the Items have a property Comments, of which we do not know whether it is one string, or a collection of zero or more strings. Furthermore every Item has a Title.
Now you want all properties of Items, each with its Comments, and a list of unique Tags of the items. Ordered by Title
One of the slower parts of database queries is the transport of the selected data from the database management system to your local process. Hence it is wise to limit the amount of data to the minimum you are really using.
It seems that the Tags of the Items are in a separate table. Every Item has zero or more Tags, every Tag belongs to exactly one item. A simple one-to-many relation with a foreign key Tag.ItemId.
If Item with Id 300 has 1000 Tags, then you know that every one of these 1000 Tags has a foreign key ItemId of which you know that it has a value of 300. What a waste if you would transport all these foreign keys to your local process.
Whenever you query data to inspect it, Select only the properties
you really plan to use. Only use Include if you plan to update the
included item.
So your query will be:
var query = myDbContext.Items
.Where(item => ...) // only if you do not want all items
.OrderBy(item => item.Title) // if you Sort here and do not need the Title
// you don't have to Select it
.Select(item => new
{ // select only the properties you plan to use
Id = item.Id,
Title = item.Title,
Comments = item.Comments, // use this if there is only one item, otherwise
Comments = item.Comments // use this version if Item has zero or more Comments
.Where(comment => ...) // only if you do not want all comments
.Select(comment => new
{ // again, select only the Comments you plan to use
Id = comment.Id,
Text = comment.Text,
// no need for the foreign key, you already know the value:
// ItemId = comment.ItemId,
})
.ToList();
Tags = item.Tags.Select(tag => new
{ // Select only the properties you need
Id = tag.Id,
Type = tag.Type,
Text = tag.Text,
// No need for the foreign key, you already know the value
// ItemId = tag.ItemId,
})
.Distinct()
.ToList(),
});
var fetchedData = await query.ToListAsync();
I haven't tried it, but I'd say you put .Distinct() in the wrong place.
var items = await _context.Items
.Include(i => i.Tags)
.Include(i => i.Comments).
.OrderBy(i => i.Title)
.Select(i => { i.Tags = i.Tags.GroupBy(x => x.Tag).Select(x => x.First()); return i; })
.ToListAsync();

Search table fields along with parent table using Foreign Key

I have 4 search fields in my index page of Employee table - id, due_date, employee_full_name, company_name.
Here, in search_parameters, I am checking if search parameters are present
search_parameters =
{:id => params[:id], :due_date => params[:due_date],
:employee_full_name => params[:employee_full_name]}
.select { |key,value| value.present?}
I am searching the columns of Employee table and it is working fine
#employees_search = Employee
.where(search_parameters, params[:id].to_i, params[:due_date],
params[:employee_full_name])
Here I am searching 'company_name' from Company table with company_id as the foreign key. This is also working fine.
#company_search = Employee
.where(company_id: Company
.where(company_name: params[:company_name]))
But I need to combine the above 2 queries so that user can search all 4 fields together. Somewhat like the below code.
#employees_search = Employee
.where(search_parameters, params[:id].to_i, params[:due_date],
params[:employee_full_name],
company_id: Company
.where(company_name: params[:company_name]))
the above query just gives search result of employee table and not the combined result. What is wrong with the queries?
Try this query using the active record querying using the or query by giving all the fields,
#employees_search = Employee
.where("id = ? or due_date = ? or employee_full_name = ?
or company_id in (?)", params[:id],params[:due_date],params[:employee_full_name],
Company.where('company_name = ?',params[:company_name]).pluck(:id))
Search all the fields in the Employee table using the '= ?' syntax and when coming to the company_id there may be multiple companies with the same name so use in (?) syntax, even if it works for single company.
This will give you all the employees with the values from the params and also including the employees who belong to that company.
This may solve your issue.
using #sravan answer, I arrived to following query, which worked perfectly.
search_parameters =
{:id => params[:id], :due_date => params[:due_date],
:employee_full_name => params[:employee_full_name],
:company_id => Company
.where('company_name = ?', params[:company_name])
.pluck(:id)}
.select { |key,value| value.present? }
#employees_search = Employee
.where(search_parameters, params[:id].to_i, params[:due_date],
params[:employee_full_name],:company_id => Company
.where('company_name = ?',params[:company])
.pluck(:id)
)

undefined method `user_id' for #<ActiveRecord::Relation:0x007f8da82da248>

I am error in the 2nd line of the code here, I have a column user_id in the Estate table. What am I doing wrong here ?
myestate = Estate.where(:Mgmt => current_user.Company)
#managements = User.where(:id => myestate.user_id)
where is returning an ActiveRecord::Relation object. Because where(:mgmt => current_user.company) could return 0, 1, or Many records, you have to tell the query what you'd like from it.
Try:
myestate = Estate.where(:Mgmt => current_user.Company).first
#managements = User.where(:id => myestate.user_id)
Getting familiar with AREL and how it works is highly recommended. You can find great info on the github page or the Active Record Query Guide

Facebook FQL Multi.Query: Joining Result Sets

I'm using Facebook's fql.multiquery for a number of different things and I'm getting the results back - just as the doctor ordered. But I can't seem to wrap my head around how to join the results so I can give them back to the user in the way I want.
I'm using HTTParty to call this:
checkin_query = {
"user_checkins" => "SELECT timestamp, coords, tagged_uids, page_id, post_id, checkin_id, message FROM checkin WHERE author_uid= me()",
"location_names" => "SELECT name FROM page WHERE page_id IN (SELECT page_id FROM #user_checkins)",
"friends_with" => "SELECT uid, name, pic_square FROM user WHERE uid IN (select tagged_uids FROM #user_checkins)"
}
params = {:queries => checkin_query.to_json, :access_token => user.token, :format => :json}
#checkin_info = HTTParty.get "https://api.facebook.com/method/fql.multiquery", :query => params
Which gives me what I want... but it's in 3 separate arrays/hashes (?) and for some reason, my brain isn't coming to a conclusion on how to deal with it.
So basically if I wanted to show the user "OK dude, you were at *LOCATION_NAME* with these people: *FRIENDS_WITH*
How can I take those 3 separate result sets and match everything up? Is there a way to include something from a previous query to call back and match it so I can display everything? Some check-ins have no tagged_uids, so obviously just doing it in order won't work when it comes to the friends they're with.
Google searches have shown me SQL's JOIN (which seems like it may be a solution) - but isn't available in FQL.
I have no experience with either FQL or HTTParty so I might have this completely wrong.
I tend to format the sql as follows:
checkin_query = {
"user_checkins" => "
SELECT tagged_uids, page_id
FROM checkin
WHERE author_uid = me()
",
"location_names" => "
SELECT name
FROM page
WHERE page_id IN (
SELECT page_id
FROM #user_checkins
)
",
"friends_with" => "
SELECT name
FROM user
WHERE uid IN (
SELECT tagged_uids
FROM #user_checkins
)
"
}
location_names and friends_with are probably returned as arrays of hashes:
"friends_with" => [{:name => 'John'}, {:name => 'Sue'}]
Not sure what HTTParty returns, but if it is hashes of arrays of hashes you might try:
puts "OK dude, you were at #{ #checkin_info[:location_names].map { |e| e.values } } with these people: #{ #checkin_info[:friends_with].map { |e| e.values } }
To figure out what #checkin_info returns you could try this:
puts #checkin_info.to_yaml

Selecting on a many table using Linq

I have a recipe table that has a related ingredients table
on one to many basis.
How do I select using Linq ingredients
that have a ingredientName column and it should contain
a specified word.
This is what I tried.
IQueryable<OurRecipes.Domain.Linq2Sql.Recipe> recipes = _dbctx.Recipes.AsQueryable();
foreach (string word in searchdata.Keywords)
{
recipes = recipes.Where(r => r.RecipeTitle.Contains(word));
recipes = recipes.Where(r => r.Ingredients.Where(i => i.IngredientName.Contains(word)));
}
I get cannot convert type 'etc' to bool error.
Any ideas
Malcolm
The error lies here:
recipes = recipes.Where(r => r.Ingredients.Where(i => i.IngredientName.Contains(word)));
The condition inside Where must return a boolean, in this case, the r.Ingredients.Where(i => i.IngredientName.Contains(word)) will not return a boolean, and hence the error.
This is how you can fix the problem:
recipes = recipes.Where(i => i.Ingredients.Any(row=>row.IngredientName.Contains(word)));
r.Ingredients.Where(i => i.IngredientName.Contains(word)));
replace with
r.Ingredients.Any(i => i.IngredientName.Contains(word)));
Btw, I like SQL like syntax more as it more netural. The same:
from r in _dbctx.Recipes
where r.Ingredients.Any(i => i.IngredientName.Contains(word)));
select r;
This will select all recipies that has ingredients with name contains word.

Resources