Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Data Model Questions /

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Silverstripe combine filterAny and filter to have an OR with an AND in it


Go to End


8 Posts   3563 Views

Avatar
Schippie

Community Member, 38 Posts

25 August 2014 at 6:43am

I have a question and maybe somebody can help me figure out what the best way would be to achieve the solution. What i wanted to do is the reverse of:

http://doc.silverstripe.com/framework/en/topics/datamodel#highlighter_745635

WHERE ("LastName" = 'Minnée' AND ("FirstName" = 'Sam' OR "Age" = '17'))

I want to get something along the lines of:

WHERE( ("LastName" = 'Minnée') OR ("FirstName" = 'Sam' AND "Age" = '17'))

Now i cannot find any way to achieve this effect seeing as i cannot add a filter within the filterAny

Avatar
swaiba

Forum Moderator, 1899 Posts

25 August 2014 at 8:22am

Well you can always use a direct ->where() clause for this - you'll need to prevent against SQL injection manually but that isn't the end of the world.

Avatar
Schippie

Community Member, 38 Posts

25 August 2014 at 11:20am

I am indeed already using the where method and all was just wondering if their was a build in way to achieve the same result.

Avatar
Kirk

Community Member, 67 Posts

25 August 2014 at 12:13pm

You may be able to use the subtract method on a data list more info is here under Subtract
http://doc.silverstripe.com/framework/en/topics/datamodel

Also a example to give you an idea

$allSams = Member::get()->filter(array('FirstName' => 'Sam', 'Age' => 17));
$allMinnee = Member::get()->filter('SurName', 'Minnée');
$noSams = $allMembers->subtract($allSams);

Avatar
(deleted)

Community Member, 473 Posts

25 August 2014 at 1:01pm

Member::get()->alterDataQuery(function($query) {
  $disjunct = $query->disjunctiveGroup();
  
  $t = new ExactMatchFilter('LastName', 'Minnée', array());
  $t->apply($disjunct);  

  $conjunct = $disjunct->conjunctiveGroup();
  $t = new ExactMatchFilter('FirstName', 'Sam', array());
  $t->apply($conjunct); 
  $t = new ExactMatchFilter('Age', '17', array());
  $t->apply($conjunct); 
});

That is what it would expand to if something nicer existed. However, this is closer you'll get to something inbuilt.

Avatar
Schippie

Community Member, 38 Posts

25 August 2014 at 5:49pm

Two great suggestions even if they are a tad cumbersome to the problem at hand. Guess those are the only ways to do it with build in functionality. Guess we can only hope to see different solutions to allow nested structures something like:

array(
   "OR" => array(
           'LastName' => 'Minée',
           'AND' => array(
                  'FirstName' => 'Sam',
                  'Age'  =>  17
            )
     )
)

Avatar
swaiba

Forum Moderator, 1899 Posts

25 August 2014 at 5:54pm

Edited: 25/08/2014 5:56pm

+1 for your suggestion Schippie
I'm neither of the correct methods are readable/logical looking to me

On the same note - if I might make a tiny hijacking - I still use explicit SQL for EXISTS statements is there a suggestion on how to handle these in the ORM? Or can I add this to the above suggestion?
(this might be worth moving to the dev list...)

Avatar
Schippie

Community Member, 38 Posts

26 August 2014 at 1:44am

Oh sure Swaiba, would be nice to see both changed. And i am not sure EXISTS has a build in functionality for it.
So would be nice to see both functionality's added.