How to decode json data in sql for search? - sql

need some advice to solve problem with yii grid/POstgreSql search.
In table I have some row let's call - some_important_data.
For showing in gridview i write some code in MyModel.php afterFind() method.
$someData = $this->some_data ? json_decode(urldecode($this->some_data)) :'';
if(!empty($someData)) {
$this->searcheeReason = $someData->csr_refuse_reason;
$this->witnessReason = $someData->csr_witness_reason;
}
........
if(!empty($this->starttime) && !empty($this->endtime) && !empty($csrPauseData->csr_colleague_reason)){
$this->status = "Rejected";
}
Now I want to write Search Part in search method in MyMethodSearch.php and Order in my controller =>
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$dataProvider->setSort([
'attributes' => [
'searchNum' => [
'asc' => ['responses.number' => SORT_ASC],
'desc' => ['csresponses.number' => SORT_DESC]
],
'searcheeReason' => ???
I try a lot of things, but I don't find any optimal way. One of that ways
=>
SELECT substring(csresponses.some_data
from (POSITION('%22csr_refuse_reason%22%3A%22' in
csresponses.some_data) +
LENGTH('%22csr_refuse_reason%22%3A%22'))
for (POSITION('%22%2C%22' in
substring(csresponses.some_data
from (POSITION('%22csr_refuse_reason%22%3A%22' in
csresponses.some_data) )
for (LENGTH( csresponses.some_data) -
POSITION('%22csr_refuse_reason%22%3A%22' in csresponses.some_data))))
- LENGTH('%22use_firstname%22%3A%22')))
from csresponses
Code written ofcourse with yii rules, it's just sql interpretation

Related

How can I order a row into first position?

I have this form :
$builder
->add('restaurantsFilter1', 'entity', [
'label' => 'Commune',
'empty_value' => 'Dans toute la Narbonnaise',
'class' => 'AppBundle:City',
'choice_label' => 'name',
'query_builder' => function (EntityRepository $er) {
return $er
->createQueryBuilder('c')
->addSelect('d')
->leftJoin('c.documents', 'd')
->where('d.type = :type')
->orderBy('c.name')
->setParameter('type', Document::T_VILLAGE)
;
},
])
which is a select which displays a list of cities.
A client told me that he needed a field "Around me" which will display all cities around 20 km.
So to do so, I created a new city in my database with this name, but now I need to put it in the first position of my select.
In sql I would use something like ORDER BY (insee_code= '[specific_code_of_the_city]') but I dont know how I could that with the query builder.
Do you have an idea how I could do that with the symfony query builder ?
EDIT: That's the exact issue that How do I return rows with a specific value first?
You could create a hidden field and order by that.
return $er
->createQueryBuilder('c')
->addSelect('CASE
WHEN c.name = "specific_code_of_city"
THEN 0
ELSE 1
END as HIDDEN presetOrder')
->addSelect('d')
->leftJoin('c.documents', 'd')
->where('d.type = :type')
->orderBy('presetOrder', 'ASC')
->addOrderBy('c.name', 'ASC')
->setParameter('type', Document::T_VILLAGE)
;

Yii 2.0 Select Pre-selected values from Database

I have been trying to fix an issue but to no avail but i am sure i will find a solution here. I am using Kartik 2.0 Select extension to do a multiple select. Fine, all working when inserting into the database but i am unable to retrieve the saved records to be displayed as selected back in the select field.
//I have included the kartik widgets already
use kartik\widgets\Select2;
<label>Desired Specialization(s)</label>
<?= $form->field($spec, 'id')->label(false)->widget(Select2::classname(), [
'data' => $model->getAllSpecializations(),
'options' => ['placeholder' => 'You can choose more than one specialization ...'],
'pluginOptions' => [
'allowClear' => true,
'multiple' => true
],
]);
?>
</div>
Please, your reply will be appreciated. Thanks
I think you need to add the saved values as the initial data? Like so:
'value' => $savedDataArray, // initial value
http://demos.krajee.com/widget-details/select2#usage-tags
After much digging into the code, i found a way on how to display selected database values into a multi-select option using Yii Select2
My Model
public function getCandidateLanguage()
{
$langValues = (new \yii\db\Query())
->select('c.language_id AS id, l.lang_name')
->from('candidate_language c ')
->innerJoin('languages l','c.language_id = l.id')
->where('c.candidate_id='.$this->candidate_id)
->orderBy('c.language_id')
->all();
return \yii\helpers\ArrayHelper::map($langValues,'id','lang_name');
}
My View
use kartik\widgets\Select2;
<?php
//the line below is to fetch the array key of $model->getCandidateLanguage() array
$lang->id = array_keys($model->getCandidateLanguage()); // value to initialize
echo Select2::widget([
'model' => $lang,
'attribute' => 'id',
'data' => $model->getAllLanguages(),
'options' => ['placeholder' => 'Choose multiple languages'],
'pluginOptions' => [
'allowClear' => true,
'multiple' => true,
'tags' => true,
],
]);
?>
Hope it help someone who is facing the same issue.

Problems returning result of CDbCriteria based query

I have a query as follows
$criteria1 = new CDbCriteria();
$criteria1->condition = 'id = 1';
$modelA=Table1::model()->find($criteria1);
I can pass it to a view and return the title and entry
$this->widget('bootstrap.widgets.TbBox', array(
title' => $modelA['title'],
'content' => $modelA['entry'] ));
Now I'd like to return a range of entries
$criteria2 = new CDbCriteria();
$criteria2->condition = 'id > 7';
$modelB=Table1::model()->findAll($criteria2);
(btw : I'm following a form as laid out here). I was expecting to be able to read the resulting array of values out as below, but ['title'] is now being seen as a undefined index (obviously I'm expecting to read this out in a loop but you get the point)
$this->widget('bootstrap.widgets.TbBox', array(
'title' => $modelB['title'][0],
'content' => $modelB['entry'][0]));
Where am I going wrong?
Thanks
No, the indexes should be specified in the different order: the number of a specific element first, then the name of the property. Additionally, it's better (=cleaner) to name the result of findAll so it'll show you (and any other reader) that it's a collection, not a single model:
$models = Table1::model()->findAll($criteria2);
// ...
$this->widget('bootstrap.widgets.TbBox', array(
'title' => $models[0]['title']
//...
));
But even that's not necessary if you use foreach (and you probably will):
foreach ($models as $model):
// ...
$this->widget('some.name', array(
'title' => $model['title']
);
endforeach;

ElasticSearch Tire two field conditional filter

I'm doing a mutli-index query With Tire and rails 3 and I want to filter out Venues who have approved => false so I need some sort of combo filter.
Here is the query
query = params[:q]
from = params.delete(:from)
size = params[:size] || 25
Tire.search(
[Venue.index_name,
Performer.index_name, User.index_name], load: true) do |s|
s.query do
string(query, fields: [:_all, :name, :title], use_dis_max: true)
end
s.from from if from
s.size size if size
end.results.to_a
This line removes all Performers and Users because they don't have an :approved field.
s.filter(:term, :approved => true )
And this line obviously removes all non-venues which is no good.
s.filter(:term, { :approved => true, :index_name => 'venues'} )
Any ideas besides adding an approved: true field to all Users and Performers? I think something like this is what I want conceptually:
s.filter(:term, :approved => true, :if => {:index_name => 'venues'} )
EDIT Thanks to Mallox I was able to find the Should construct but I'm still struggling to implement it Tire. It seems like the below code should work but it return no results on any query. I also remove the "{:terms => { :index_name => ["performers", "users"]}}," to make sure it wasn't my use of index name or multiple lines of query that was the problem and still no luck. Can anybody shed some light on how to do this in Tire?
s.filter(:bool, :should => [
{:terms => { :index_name => ["performers", "users"]}},
{:term => { :approved => true}},
] )
So i have little knowledge about Ruby and Tire, but the ElasticSearch query that you want to build would be based on a bool filter, that contains some "should" entries (which would translate into inclusive OR).
So in your case something along the lines of:
"filter" : {
"bool" : {
"should" : [
{
"terms" : { "_type" : ["Performers","Users"] }
},
{
"term" : { "approved" : true }
}
]
}
}
Take a look at the documentation here, maybe that'll help:
:http://www.elasticsearch.org/guide/reference/query-dsl/bool-filter/

conditional update_all with join tables in ActiveRecord?

The following query returns the collection of AR objects that I want to update:
Variant.all(:joins => { :candy_product => :candy }, :conditions => "candies.name = 'Skittles'")
I'm trying to do something like the following:
Variant.update_all(:price => 5, :joins => { :candy_product => :candy }, :conditions => "candies.name = 'Skittles'")
This should only update the price for the variants returned from original query. Is this possible with AR or will I have to write the SQL? This is a pretty large collection, so anything that iterates is out.
Using Rails 2.3.4.
As #François Beausoleil pointed correctly we should use scoped
Variant.scoped(:joins => { :candy_product => :candy }, :conditions => "candies.name = 'Skittles'").update_all(:price => 5)