Wordpress Custom Taxonomy Search - sql

I'm trying to implement search, which will look through custom taxonomy terms.
I have custom type called "product", and custom taxonomy called "type". When I'm using wordpress standard form it works good except the fact, that it doesn't search in custom taxonomy terms.
So, what I need is:
1. Make WP search through "m_type" taxonomy terms
2. It should use "name" of the term, instead of "slug".
I was trying to include additional query vars to make it look through "slugs" at least.
This code:
$wp_query->query['tax_query'] = array(
array(
'taxonomy' => 'm_type',
'field' => 'slug',
'terms' => 'pen'
)
);
Generates the following SQL:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts INNER JOIN wp_term_relationships
ON (wp_posts.ID = wp_term_relationships.object_id) INNER JOIN wp_postmeta ON
(wp_posts.ID = wp_postmeta.post_id) WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id
IN (163) ) AND (((wp_posts.post_title LIKE '%pen%') OR (wp_posts.post_content LIKE
'%pen%'))) AND wp_posts.post_type IN ('product') AND (wp_posts.post_status
= 'publish' OR wp_posts.post_author = 1 AND wp_posts.post_status = 'private') AND
(wp_postmeta.meta_key = 'max_price' ) GROUP BY wp_posts.ID
ORDER BY wp_postmeta.meta_value+0 DESC LIMIT 0, 60
So, basically it adds custom taxonomy, search through posts, that have this kind of taxonomy (*wp_term_relationships.term_taxonomy_id IN (163)*) but actually never compares taxonomy term with query string.
Maybe I'm doing all of this wrong?

I am using this sql query to fetch results on the basis of title/taxonomy term/content search where $search is the search parameter and $_REQUEST['post_type'] that I am p
SELECT DISTINCT(ID) FROM
$wpdb->terms AS terms
JOIN
$wpdb->term_taxonomy as termtaxonomy
JOIN
$wpdb->term_relationships AS termrelationship
JOIN
$wpdb->posts AS posts
ON terms.term_id = termtaxonomy.term_id &&
termrelationship.term_taxonomy_id = termtaxonomy.term_taxonomy_id &&
termrelationship.object_id = posts.ID
WHERE terms.name LIKE '%".$search."%' OR posts.post_title LIKE '%".$search."%' OR posts.post_content LIKE '%".$search."%' AND posts.post_type='".$_REQUEST['post_type']

Related

How to use joins with `where` condition

I want to get users with their assets, which have type 'Google'.
I tried
User.joins(:assets).where(assets: { assetable_type: 'Google' })
or
User.joins(:assets).where("assets.assetable_type = 'Google'")
But that scopes work identically and return nothing.
SQL, which scopes generate:
SELECT "users".* FROM "users" INNER JOIN "assets" ON "assets"."assetable_id" = "users"."id" AND "assets"."assetable_type" = 'User' WHERE (assets.assetable_type = 'Google')
It doesn't seem to look right
What am I doing wrong?
You didn't gave any details about your models and associations
So, I can give you a temporary solution to use raw sql
sql = "SELECT users.* FROM users INNER JOIN assets ON assets.assetable_id = users.id WHERE assets.assetable_type = 'Google'"
result = ActiveRecord::Base.connection.execute(sql).to_a
Note: If you are using relation as per rails standards it should be
sql = "SELECT users.* FROM users INNER JOIN assets ON assets.assetable_id = users.id WHERE assets.assetable_type = 'Google'"
result = ActiveRecord::Base.connection.execute(sql).to_a
But I think you are using another name i.e., assetable_id instead of user_id.

How to get posts from a category using SQL query in Wordpress

I need to get posts from a category using SQL query in Wordpress, so i use get_resilts but it returns an empty array...please could someone tell me what is wrong in my code...? thanks a lot
$wpdb->get_results("
SELECT ID, post_date
FROM {$wpdb->prefix}posts
LEFT JOIN $wpdb->term_relationships ON
($wpdb->posts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON
($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
WHERE $wpdb->posts.post_type = 'post'
AND $wpdb->term_taxonomy.taxonomy = 'category'
AND $wpdb->term_taxonomy.term_id = 18
);
Is there a particular need to use an SQL query with $wpdb?
This can be easily be achieved using WordPress functions:
$args = array( 'post_type' => 'post', 'category' => 18 );
$myposts = get_posts( $args );
If using SQL is an absolute requirement you'll want to fix your query.
This is correct:
FROM {$wpdb->prefix}posts
This is not:
LEFT JOIN $wpdb->term_relationships ON

Write Nested Select Query in Laravel 5.3

How do I write a complex query in Laravel 5.3? I am trying but not getting the result I expect.
Query
SELECT * FROM (SELECT posts.post_id
FROM posts
WHERE ((posts.user_id = 1 AND posts.user_type = 'user')
OR (posts.user_id IN (1) AND posts.user_type = 'page'))) posts
WHERE posts.post_id > '0' ORDER BY posts.post_id DESC
Please help me write this using Laravel Query Builder.
#Punit Gajjar has provided one solution, but that's not quite what your question was given the terms Query Builder. His solution will work, but half it it doesn't make use of the query builder (it's just a copy/paste and throwing your SQL into a raw query, which is essentially exactly the same thing as you had before) and therefore I feel it's necessary to provide you with an additional option:
Post::where('post_id', '>', 0)
->where(function($query) {
$query->where(function($subquery) {
$subquery->where('user_id', 1)->where('user_type', 'user');
})->orWhere(function($subquery) {
$subquery->whereIn('user_id', [1])->where('user_type', 'page');
});
})
->orderBy('post_id', 'DESC')
->get();
I've kept variables names short just for readability purposes, but the argument in the anonymous functions ($query and $subquery) are the query builder instances.
Here is your answer .
$MyQuery = DB::table(DB::Raw("(SELECT
posts.post_id
FROM
posts
WHERE
(
(
posts.user_id = 1
AND posts.user_type = 'user'
)
OR
(
posts.user_id IN (1)
AND posts.user_type = 'page'
)
)
)"))
->where('posts.post_id','>',"0")->orderBy("posts.post_id" , "DESC")->get();
Try printing query once using ->toSql() like this
echo $MyQuery = DB::table(DB::Raw("(SELECT
posts.post_id
FROM
posts
WHERE((
posts.user_id = 1
AND posts.user_type = 'user'
)
OR(
posts.user_id IN (1)
AND posts.user_type = 'page'
)))"))
->where('posts.post_id','>',"0")->orderBy("posts.post_id" , "DESC")->toSql();
die();

Ransack no implicit conversion of Ransack::Search into Array

I am currently implementing Ransack for searching functionality.
I have a model Campaigns which collaborates campaigns that the user directly created as well as others so long as the user belongs to the same vendor.
I can combine the results as such:
#search = current_user.campaigns + current_user.vendor.campaigns.where.not(:user_id => current_user.id)
Problem with this is that Ransack will not accept this combination and spits out
no implicit conversion of Ransack::Search into Array
Can someone point me in the direction on how to refactor this code?
TIA
Adding Addition Data
When looking at my console I can see *current_user.campaigns*:
Campaign Load (0.3ms)
SELECT DISTINCT "campaigns".* FROM "campaigns"
WHERE "campaigns"."user_id" = ? [["user_id", 2]]
Running *current_user.vendor.campaigns* give me:
Campaign Load (0.4ms)
SELECT DISTINCT "campaigns".* FROM "campaigns"
INNER JOIN "weeks" ON "campaigns"."id" = "weeks"."campaign_id"
INNER JOIN "products" ON "weeks"."product_id" = "products"."id"
INNER JOIN "locations" ON "products"."location_id" = "locations"."id"
WHERE "locations"."vendor_id" = ? [["vendor_id", 2]]
I can get the first filter of current_user achieved with:
#search = Campaign.where("campaigns.user_id" => current_user.id).search(params[:q])
But I am lost of how I go about building the rest of the join tables to include both elements of data
Solved
#search = Campaign.includes(:weeks).where('(campaigns.user_id LIKE ?) OR (weeks.vendor_id LIKE ?)', current_user.id, current_user.vendor.id).search(params[:q])

Complex query, use :includes and :joins at the same time?

(Using Rails 3.1.3)
I have an app that manages products. I import the products from several resellers and they all name their categories different. Because of this I have resellercategories that are mapped to my own subcategories.
Categories
Subcategories (belongs_to Category)
Resellercategories (belongs_to Subcategory)
Products (belongs_to Resellercategory)
You can see the models and how the relations are defined here:
http://snipt.net/Linuus/category-and-subcategory?key=38ba590408ac4233927a06046eeca30d
On my site I want to display the categories and their subcategories, easy.
If a user filters the products for, say, only 'female' products I want to filter also the categories and subcategories so that only categories and subcategories that have 'female' products are displayed. The gender is stored in the products.
So, how can I do this?
I tried to create a query like this:
http://snipt.net/Linuus/categories-1/?key=2d5d54fd573f0afe60eaa3c47a23fd4d
which (I think) filters the correct Categories. However, when I do something like:
#menu_categories.each do |c|
c.subcategories.each do |sc|
# do something...
end
end
It still queries all the subcategories whether or not they have female products. So, I got a suggestion over at the Ruby on Rails Google Group to eagerly load the :subcategories using .includes(). So, something like this:
Category.includes(:subcategories)
.joins("INNER JOIN resellercategories AS r ON subcategories.id = r.subcategory_id")
.joins("INNER JOIN products AS p ON r.id = p.resellercategory_id")
.group("categories.id")
.order("categories.name ASC")
.where("p.gender = 'unisex' OR p.gender = 'female'")
.where("subcategories.id > 0") # Dummy to trigger eager loading
However, when mixing .includes() and .joins() the includes seems to fail to eager load anything. Thus throwing the error below:
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: subcategories.id:
SELECT "categories".* FROM "categories"
INNER JOIN resellercategories AS r ON subcategories.id = r.subcategory_id
INNER JOIN products AS p ON r.id = p.resellercategory_id
WHERE (p.gender = 'unisex' OR p.gender = 'female')
GROUP BY categories.id
ORDER BY categories.name ASC
Is this behavior expected? Is it a bug?
Am I trying to do this the right way or is there a better way to do it?
Any help is very appreciated.
(The discussion on RoR Google Group: https://groups.google.com/forum/?pli=1#!topic/rubyonrails-talk/UkCF7jbehHk)
Solution:
Ok, so the solution is to use eager_load() instead of includes(). I also had to remove group()
This seems to work for me:
Category.eager_load(:subcategories)
.joins("INNER JOIN resellercategories AS r ON subcategories.id = r.subcategory_id")
.joins("INNER JOIN products AS p ON r.id = p.resellercategory_id")
.order("categories.name ASC")
.where("p.gender = 'unisex' OR p.gender = 'female'")
Rails does not always use joins to realise an include. You can force it too by doing eager_load rather than includes.
This AR chain looks a lot cleaner.
Category.joins({:subcategories =>
{:resellercategories =>
:products}})
.includes(:subcategories)
.where('products.gender = unisex OR
products.gender = ?', gender)
BUT I don't think it will solve your original problem of getting all the subcategories. To solve that you'll actually have to query the association.
#menu_categories.each do |c|
c.subcategories.joins({:resellercategories =>
:products}})
.where('products.gender = unisex OR
products.gender = ?', gender)
.each do |sc|
# do something...
end
end