jedrzej / searchable Goto Github PK
View Code? Open in Web Editor NEWSearch/filter functionality for Laravel's Eloquent models
License: MIT License
Search/filter functionality for Laravel's Eloquent models
License: MIT License
I have this problem, when i use LIKE operator. I want to filter %Carlos%, but dont work because Builder resolve this: "value" => b"Êrlos%".
` protected function processSearchFilter(Builder $builder, Constraint $constraint)
{
// this logic should happen for LIKE/EQUAL operators only
if ($constraint->getOperator() === Constraint::OPERATOR_LIKE || $constraint->getOperator() === Constraint::OPERATOR_EQUAL) {
$builder->whereHas('tercero',function ($query) use ($constraint) {
$query->where('nombre1', $constraint->getOperator(), $constraint->getValue())
->orWhere('nombre2', $constraint->getOperator(), $constraint->getValue())
->orWhere('apellido1', $constraint->getOperator(), $constraint->getValue())
->orWhere('apellido2', $constraint->getOperator(), $constraint->getValue())
->orWhere('identificacion', $constraint->getOperator(), $constraint->getValue());
});
return true;
}
// default logic should be executed otherwise
return false;
}`
Hello i have noticed there is no way to do a where between.
And overriding the filter doesn't work either sense the filter method is beeing hit twice and not once with an array of the constraints.
Consider this:
date[]=2016-07-26&date[]=2016-07-29
This makes the dateProgressFilter beeing hit but its beeing hitted twice.
So i have a single value to work with..
Is it possible to somehow get both constraint objects a once so i can do something like the fallowing:
$builder->whereBetween()
Sometimes, I just want to search where a given field is null.
Now when empty string is provided "LIKE '%%'" is generated
For example, we have a small service for blog posts management and a blog itself.
At our search, we want to do the following query:
'query' => [
'mode' => 'or',
'city' => "%$query%",
'state' => "%$query%",
'store_name' => "%$query%",
'title' => "%$query%",
],
Thats nice, it will search for everything we need but we want to filter by published posts also. But, Its not possible since we're using OR mode.
Is there a way to make something like?
'query' => [
'mode' => 'and',
'status' => 'published',
[
'mode' => 'or',
'city' => "%$query%",
'state' => "%$query%",
'store_name' => "%$query%",
'title' => "%$query%",
],
],
I am using postgres, where LIKE is case sensitive. This does not provide best experience with filters. ILIKE should be used in this case.
Can this be fixed?
?id[]=1&id[]=2 instead of ?id=1,2
Is it possible to search for content, like "Smith, John"?
Right now, it is looking for "Smith" OR "John".
Is there some kind of config to disable "OR" functionality for comma, or change it to another character?
At the moment it's possible to do positive search by relation - find records that have matching related records. It's needed to allow also negative search - find records that don't have matching related records.
Usually users do not input operators like (ge)2018-04-16
It make view code little hacky like change values before send
I think operators should be in query keys, not values like below
Now
<input name="foo" value="(ge)2018-04-16">
My opinion
<input name="(ge)foo" value="2018-04-16">
I'm filtering on a model but a filed like created_at appears in many of my models so this is causing an error whereby created_at is ambiguous. I believe this occurs because I am running pimp()
on a relation instead on the model itself. How can I fix this?
$user->transactions()->pimp()
@jedrzej Is this still maintained?
The package now allows to search only among fiields of given searchable models. The scope of this issue is to add possibility to filter also fields of related models (one-to-one, many-to-one, many-to-many relations)
Today, is not possible to make relationship search.
I installed pimpable package, but I think the problem is with searchable package.
When I have something like this:
Model::pimp()->simplePaginate();
It gives me:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'page' in 'where clause' (SQL: select * from
sectionspage = 1 limit 16 offset 0)
I found a way to allow everything except 'page' attribute, but it would be nice to have this effect in package.
My implementation in Model;
protected function getSearchableAttributes() { return array_except(Input::all(), 'page'); } // or something like this public $searchableExcept = ['page'];
Hello, pleasure, first of all to thank the developers for the beautiful work. I've been looking for something like this for some time.
Sorry I'm Brazilian so my English isn't very good, it's just technical.
I would like to know if with this tool I can do the research of several fields through just one attribute.
Example:
posts?search=%searchstring%
colums search: [title, desc, keyword]
When using this package to search multiple relations using the OR mode the query generated is not produced as expected. For example, consider the following if we have a one to one relation between "providers" and "users" where the users table contains first_name and last_name and the providers table has a user_id column:
?user:first_name&user:last_name&mode=or will generate the following query
where exists (select * from `users` where `providers`.`user_id` = `users`.`id` and (`last_name` = ?)) **and**
exists (select * from `users` where `providers`.`user_id` = `users`.`id` and (`first_name` = ?))
The expected result would be
where exists (select * from `users` where `providers`.`user_id` = `users`.`id` and (`last_name` = ?)) **OR**
exists (select * from `users` where `providers`.`user_id` = `users`.`id` and (`first_name` = ?))
As a side note, I believe this query should actually group the two queries under the same subquery like this:
where exists (select * from `users` where `providers`.`user_id` = `users`.`id` and (`last_name` = ? OR `first_name` = ?))
however I believe this is a separate issue. I propose the following changes in Constraint.php
public function apply(Builder $builder, $field, $mode = Constraint::MODE_AND)
{
if ($this->isRelation($field)) {
list($relation, $field) = $this->splitRelationField($field);
if (static::parseIsNegation($relation)) {
$builder->doesntHave($relation, $mode, function (Builder $builder) use ($field, $mode) {
$this->doApply($builder, $field, $mode);
});
} else {
$builder->has($relation,'>=',1,$mode, function (Builder $builder) use ($field, $mode) {
$this->doApply($builder, $field, $mode);
});
}
} else {
$this->doApply($builder, $field, $mode);
}
}
Where the ->whereDoesntHave() is replaced with doesntHave() passing in the $mode and the whereHas() is replaced with has(). This could actully simplify the doApply() function as well instead of resolving the method name 'whereIn' 'orWhereIn' etc, the $mode could be passed in directly the function.
Some of users of model Student have foreign key to model User. I create relation student() in model User with hasOne() to join them. Now in model User I need to filter those who are student. How can I do that?
I tried
public $searchable = ['name', 'mobile', 'email', 'id', 'student:id'];
and in string query I set
student:id=(null)
and doesn't work because the relation doesn't exist in the first place.
Now it's possible to override a filter by implementing processAttributeFilter method in the model. Similar functionality should exist for relation filters.
Now if you do ?mode=or in URL mode will be changed to OR but also filter mode=or will be applied on a model
Hi,
?start_date[]=(ge)2018-08-01&start_date[]=(le)2018-08-02
translates to the following MySQL query:
WHERE `start_date` >= 2018-08-01
AND
`start_date` <= 2018-08-02
Which is the expected result. However,
?instances:start_date[]=(ge)2018-08-01&instances:start_date[]=(le)2018-08-02
becomes
WHERE EXISTS
(
SELECT *
FROM `expedition_instances`
WHERE `expeditions`.`id` = `expedition_instances`.`expedition_id`
AND `start_date` >= '2018-08-01')
AND
EXISTS
(
SELECT *
FROM `expedition_instances`
WHERE `expeditions`.`id` = `expedition_instances`.`expedition_id`
AND `start_date` <= '2018-08-02')
The expected result is
WHERE EXISTS
(
SELECT *
FROM `expedition_instances`
WHERE `expeditions`.`id` = `expedition_instances`.`expedition_id`
WHERE `start_date` >= 2018-08-01
AND `start_date` <= 2018-08-02 )
Feel free to change the issue's title, I wasn't able to think of any better name for it atm.
The constraints looks correctly grouped into instances:start_date
:
/expeditions?with[]=instances&instances:start_date[]=(ge)2018-08-01&instances:start_date[]=(le)2018-08-02
array(1) {
["instances:start_date"]=>
array(2) {
[0]=>
object(Jedrzej\Searchable\Constraint)#715 (3) {
["operator":protected]=>
string(2) ">="
["value":protected]=>
string(10) "2018-08-01"
["is_negation":protected]=>
bool(false)
}
[1]=>
object(Jedrzej\Searchable\Constraint)#716 (3) {
["operator":protected]=>
string(2) "<="
["value":protected]=>
string(10) "2018-08-02"
["is_negation":protected]=>
bool(false)
}
}
}
I think that all constraints of the group should be applied when doing
$builder->whereHas($relation, function (Builder $builder) use ($field, $mode) {
$this->doApply($builder, $field, $mode);
});
Something like
$builder->whereHas($relation, function (Builder $builder) use ($constraints, $mode) {
foreach($constraints as $constraint){
$this->doApply($builder, $constraint->field, $mode);
}
});
Of course that's just hypothetical, there is no access to the group of the same constraints as they are isolated in buildConstraints
(Jedrzej/Searchable/SearchableTrait.php#L120)
Current version of the package allows only searching using AND operator on all criteria - meaning that all criteria need to be met in order to record to be returned. The scope of this issue is to allow switching to OR search - the result of such search are records that meet any of given criteria. One example of such feature being useful is searching among multiple text fields (email, username, first/last name) for some kind of user autosuggest.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.