i have a db structure like this:
Addresses
id primary key auto_increment
name
surname
email
categories
id primary key auto_increment
name
address_category
id primary key auto_increment
addr_id
cate_id
on the gridview, into categories filter column i have inserted a select2 extension with multiple set to true and on the addressesSearch model i have added this code:
->andFilterWhere(['address_category.cate_id'=> $category]
it function but not like i want, yii make a IN query like cate_id IN (4,5,6) instead i need a query that find the address that are tagged with all the categories selected.
i hope to have explained well my problem
thanks
select2 multiple returns comma separated values. split it first, maybe check for integer values
->andFilterWhere(['IN', 'address_category.cate_id', array_map('intval', explode(',', $category))]);
i have find a solution, i don't know if is the best way but works.
$query->select(['addresses.*, (select count(*) as categories from address_category where cate_id IN ('.implode(",",$category).') and addr_id=addresses.id) as categories']);
$query->having(['categories' => count($category)]);
I believe the OP's working solution may use a calculated field in the query, and that possibly ties-in with a solution that eventually worked for me, so this might just be an alternative approach. Note: I tried everything to parse/manipulate the attribute, but nothing worked.
So create a field in your model using a (getter), that simply replicates the attribute, so in a model which has a getter for a Country name in a country table with country_id as the attribute, something like:
public function getCountrylink()
{
return $this->country_id;
}
This (countryLink) is then used as the attribute in the view/index and as a simple replacement in the modelSearch filter:
$query->andFilterWhere(['country_id' => $this->countryLink]);
N.B. You'll also need to add the calc field as a public variable and include as a safe entry in the rules in the modelSearch, as per standard instructions for establishing a calculated field (search for "Filter & Sort by calculated/related fields in GridView Yii 2.0").
Related
I have a author table and a publication table. Both are related to each other in a many to many relation. When I'm inserting the publications the authors of the publications are inserted in the pivot table by the order of authors id. But I need to insert it by the order i'm selecting the authors in the front-end. Whatever the order of the authors in the front end is it is getting ordered by the author's id in the pivot table. How can i stop this automatic ordering
You can't add rows in a specific order into a pivot table, because it doesn't really make sense.
Let's consider an users table:
The first user you enter will have the id 1
The second will be assigned to the id 2
And so on...
So you can enter the users in a specific order and retrieve them by their id.
However, in a standard pivot table, the primary key is composed by two columns, in your case the author_id and publication_id. Nothing new is created here, you just associate the primary key of two existing rows in two differents tables in order to achieve one - and unique - composed primary key.
If i explained well (and i hope so :p), you should understand why saying
But I need to insert it by the order i'm selecting the authors in the front-end.
doesn't really make sense.
But, don't worry, it is still possible to achieve your goal here.
Instead of using a pivot table, you can use a normal table with an id. This way, the order of insertion will be preserved. It will work but that's not very nice.
A better approach would be to add an additional column to the pivot table. A column like position. This column could be incremented for each author you insert. Then, you can order the table by the position column, by simply adding ->orderBy('position') to your relationship or every queries that needs to.
Here is an example to illustrate what i said above:
foreach($authors as $position => $author)
{
$publication->authors()->attach($author, ['position' => $position]);
}
If $authors contains the authors in the order you selected them on the front-end, they will be added accordingly.
If you need to sync instead of attach, that's also possible, it's just a little bit more verbose:
$syncData = $authors->mapWithKeys(function($author, $position){
return [$author->id => ['position' => $position]];
});
$publication->authors()->sync($syncData);
Don't forget that you can add false as a second parameter on the sync method so it'll only add new authors.
After that, just change your authors relationship in your Publication model like this:
public function authors(){
return $this->belongsToMany(Author::class)->orderBy('position');
}
Or everywhere you need to:
$publication->authors()->orderBy('position')->get();
I hope it helps !
I have a table "products" for my website. There is the product_id, image and bunch of information like manufacturer, health, age etc. When I started to work on my projekts I chose to save everything as ENUMs like this:
manufacturer ENUM('manufacturer1', 'manufacturer2', 'manufacturer3', 'manufacturer4'),
However dealing with more stuff I have realized that this is not the best approach for me. So I decided to create reference tables. For manufacturer it looks like this:
CREATE TABLE manufacturer(
manufacturer_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
PRIMARY KEY (manufacturer_id ),
UNIQUE INDEX name (name)
);
but in products table I now have:
manufacturer_id INT(10),
The question is on what is the best way to assign value from reference table. I am using CI framework and it was very easy to display product in view. However now when I run query for product I get "3" instead of "manufacturer3".
I could use JOIN but I would have 7 JOINs. I created library with function that ataches the value. But I have to save all the possible values in that function or to query every reference table every time I use library.
I mean there are a lot of articles about why not to use ENUMs and I get that - I run in problems with ENUM in my project myself. I dont get how to convert those reference ids to real value (efectivelly, I dont think that 7 JOINs is a good way to that especially if I have to do that very often)
When I first time filter or sort the field of gridview ,after that enable the relational data field sorting link,
so, how can i solve this issue.
Here i attached two image that describe the before filtering or sorting and after that.
Link Url :
before filter: http://i.stack.imgur.com/bDJoG.png
after filter: http://i.stack.imgur.com/lXnfY.png
Updated:
I have a two table one of is student_info and second one is student_trans. and i create relation student_info_id (primary key) with student_trans_info_id like (student_info_id = student_trans_info_id),
Now in student_trans grid view i used the student_info's first_name and last_name field with sorting and filtering, but these relational field's sorting link enable after filter or sort the any filed of student_trans grid view field.
After do googling i found my mistake.
My mistake was that i added $dataProvider->sort->attributes[] code after $this->load(); function; so it mean after loading the filtered data than enable sorting link.
Now, i resolved my mistake with put the $dataProvider->sort->attributes[] before $this->load(); function.
Thanks to **#Paul van Schayck** post....
i am using cakephp 1.3 to generate a form i am creating a select list using hasOne and belongsTo relation
my models: image, category
category hasMany image
image belongsTo Category
category table has two columns id and category_name
i am doing
$this->set('categories',
$this->Image->Category->find(
'list',
array( 'order' => 'category_name ASC' )
)
); //to generate the select list
so far so good, there is only one problem left, the select list generated shows the id of the category instead of the category_name as the option text, i know this is not cakePHP's fault but i need to know the solution
any help please.
P.S if i am unclear about the question please let me know
You need to define the displayField property in your category model, so that CakePHP can properly determine which field to display as a label. This code in your category model will fix it for you:
var $displayField = 'category_name';
Alternatively, rename the category_name field to 'name' or 'title' (I would do this, it's obvious that a 'name' field in a category table is going to be the name of the category).
When in doubt, read the manual:
3.7.3.1.4 find('list')
When calling find('list') the fields passed are used to determine what should be used as the array key, value and optionally what to group the results by. By default the primary key for the model is used for the key, and the display field (which can be configured using the model attribute displayField) is used for the value.
Hey I have two models User and City, where a user belongs to a city and a city has many users.
On the city table I have city_id and city_name.
I've used used cake bake and created the user model and when I add a new user the combos box under the city field is showing the id of the city instead of the name.
I've tried several methods to show the name of city instead of the id but I've failed.
You don't mention what you've tried, but usually you'd use the model's displayName property to set the field that should be used a record's "title". In your case, I'd think:
$this->displayName = 'city_name';
Note that in 1.3, it looks like the attribute name is displayField rather than displayName.
Cake requires a specific table layout for the automation to work. Rob explained how to get around it. But if you want to avoid writing the extra lines of code, you should consider organizing your tables accordingly.
CREATE TABLE `cities` (
`id` int(11) AUTO_INCREMENT NOT NULL,
`name` varchar(25) NOT NULL,
PRIMARY KEY (`id`)
)
When you bake this model, Cake will automatically use name as the display name. This will apply to every table you create. In addition, if you use id for the table, it will automatically know how to reference it as a foreign key from other tables as city_id.