How to make where condition include nil value - ruby-on-rails

I find ActiveRecord, funnel value is not "input" value
and I make where condition
here is my code
#calls = Call.searchable.where.not(funnel: "input")
these command work good, but result is also except nil value
I wanna only funnel is not 'input'
how to add OR condition in where statement
SQL Statement is
select * from call where is_visible = 1 and (funnel != 'input or funnel is null)

The blow code should help you.
#calls = Call.searchable.where("funnel != 'input' or funnel is null")

This will also work if values are dynamic
Call.searchable.where("funnel != ? OR funnel is ?”,#value1, nil)

Related

Understanding query method where in ActiveRecord

I want to return the count of users that that have a boolean value, show, not set to true. show is a boolean but is initialized to nil.
Because of this I'm getting some results that I did not expected. For example,
[{show: nil}].where.not(show: true).count -> 0
[{show: nil}].where(show: [nil, false]).count -> 1
Shouldn't this query's return the same thing?
This is a general misunderstanding of NULL (which is not uncommon by the way).
NULL is not comparable, it is neither true or false, nor equal or not equal, nor less than or greater than, etc., NULL cannot even be compared to NULL. e.g. NULL = NULL is false but NULL != NULL is also false.
Your First case (.where.not(show: true)) is show != true (or NOT(show =true)) which is the equivalent of show = false.
Your second example (.where(show: [nil, false])) is show IS NULL OR show = false. While this syntax show: [x,y] usually results in an IN() clause Arel is smart enough to realize that one of these values is nil and converts the SQL generation accordingly because show IN (NULL,false) would be equivalent to show = NULL OR show = false (this is how IN() works) but as mentioned NULL = NULL is false thus why IS NULL and IS NOT NULL exist.
The result of your query is because there are no rows where show = false but there is one row where show IS NULL.

How to make a request for records where the value of the two fields match in mongoalchemy?

I have a model for mongoalchemy:
class ImportProductReport(mongo.Document):
target = mongo.IntField(default=0)
processed = mongo.IntField(default=0)
is_in_process_remove_offers = mongo.BoolField(default=False)
is_old_offers_removed = mongo.BoolField(default=False)
...
I need get records, where
ImportProductReport.is_in_process_remove_offers == False,
ImportProductReport.is_old_offers_removed == False,
ImportProductReport.target == ImportProductReport.processed.
Without last equal, all work good:
res = ImportProductReport.query\
.filter(
ImportProductReport.is_old_offers_removed == False,
ImportProductReport.is_in_process_remove_offers == False
)\
.all()
But if I try to write something like this:
res = ImportProductReport.query\
.filter(
ImportProductReport.is_old_offers_removed == False,
ImportProductReport.is_in_process_remove_offers == False,
ImportProductReport.target == ImportProductReport.processed
)\
.all()
I have an error:
AttributeError: 'bool' object has no attribute 'obj'
Tell me, please, how to add this last condition in my query? :)
If it someone help, I found the answer to my question.
Mongoalchemy allows queries with a syntax, similar to the syntax of the original MongoDB.
Therefore, query, that I need, can be written as follows:
res = ImportProductReport.query\
.filter({
'is_old_offers_removed': False,
'is_in_process_remove_offers': False,
'$where': 'this.target == this.processed'
})\
.all()

Include () method not loading in some conditions

I have the following EF query :
var result = (from t in context.Tickets.Include("Priority").Include("Status")
where t.TicketOpenBy.Id == user.Id
select t).Include(t => t.TicketOpenBy);
I also try
context.Tickets.Where(t => t.TicketOpenBy.Id == userId).Include("Priority").Include("Status").Include("TicketOpenBy");
When i receive the list, for each row, the object "TicketOpenBy" has all fields null.
But when i change the "where" with this condition :
"where t.TicketOpenBy.Id != user.Id"
I receive my object with all properties included.
I don't understand this behaviour. What am I doing wrong?

LINQ query with omitted user input

so I have a form with several fields which are criteria for searching in a database.
I want to formulate a query using LINQ like so:
var Coll = (from obj in table where value1 = criteria1 && value2 = criteria2...)
and so on.
My problem is, I don't want to write it using If statements to check if every field has been filled in, nor do I want to make separate methods for the various search cases (criteria 1 and criteria 5 input; criteria 2 and criteria 3 input ... etc.)
So my question is: How can I achieve this without writing an excessive amount of code? If I just write in the query with comparison, will it screw up the return values if the user inputs only SOME values?
Thanks for your help.
Yes, it will screw up.
I would go with the ifs, I don't see what's wrong with them:
var query = table;
if(criteria1 != null)
query = query.Where(x => x.Value1 == criteria1);
if(criteria2 != null)
query = query.Where(x => x.Value2 == criteria2);
If you have a lot of criteria you could use expressions, a dictionary and a loop to cut down on the repetitive code.
In an ASP.NET MVC app, chances are your user input is coming from a form which is being POSTed to your server. In that case, you can make use of strongly-typed views, using a viewmodel with [Required] on the criteria that MUST be provided. Then you wrap your method in if (ModelState.IsValid) { ... } and you've excluded all the cases where the user hasn't given you something they need.
Beyond that, if you can collect your criteria into a list, you can filter it. So, you could do something like this:
filterBy = userValues.Where(v => v != null);
var Coll = (from obj in table where filterBy.Contains(value1) select obj);
You can make this more complex by having a Dictionary (or Lookup for non-unique keys) that contains a user-entered value along with some label (an enum, perhaps) that tells you which field they're filtering by, and then you can group them by that label to separate out the filters for each field, and then filter as above. You could even have a custom SearchFilter object that contains other info, so you can have filters with AND, NOT and OR conditions...
Failing that, you can remember that until you trigger evaluation of an IQueryable, it doesn't hit the database, so you can just do this:
var Coll = (from obj in table where value1 == requiredCriteria select obj);
if(criteria1 != null)
{
query = query.Where(x => x.Value1 == criteria1);
}
//etc...
if(criteria5 != null)
{
query = query.Where(x => x.Value5 == criteria5);
}
return query.ToList();
That first line applies any criteria that MUST be there; if there aren't any mandatory ones then it could just be var Coll = table;.
That will add any criteria that are provided will be applied, any that aren't will be ignored, you catch all the possible combinations, and only one query is made at the end when you .ToList() it.
As I understand of your question you want to centralize multiple if for the sake of readability; if I were right the following would be one of some possible solutions
Func<object, object, bool> CheckValueWithAnd = (x, y) => x == null ? true : x==y;
var query = from obj in table
where CheckValue(obj.value1, criteria1) &&
CheckValue(obj.value2, criteria2) &&
...
select obj;
It ls flexible because in different situations or scenarios you can change the function in the way that fulfill your expectation and you do not need to have multiple if.
If you want to use OR operand in your expression you need to have second function
Func<object, object, bool> CheckValueWithOr = (x, y) => x == null ? false : x==y;

how can I use FirstOrDefault()?

I have this code and I want to set a value to Viewdate when the expression returns no data:
ViewData["Fix"] = db.PreStatusViws.Where(c => c.LkpNameFix == "1").FirstOrDefault().NumCoefficientFix;
can I set zero or a "Text" for that? I no, what can I do?!
note: FirstOrDefault(null) cause an error.
If I understand your question correctly, the following code should solve your problem:
var p = db.PreStatusViws.Where(c => c.LkpNameFix == "1").FirstOrDefault();
if(p != null)
ViewData["Fix"] = p.NumCoefficientFix;
else
ViewData["Fix"] = 0;
Default will return the default for the data type. If the data type in that place is a reference type (e.g. string) the default value will always be null, and therefore the following .NumsCoefficientFix member will throw a NullReferenceException.
The default value is built into .NET and not changeable, and is always given if the result set contains no value.
#Mikey has already given the code sample in his answer that I would suggest.
If you first select the numeric column, FirstOrDefault will work as you intend, returning either a value or 0 (the default for numeric types):
ViewData["Fix"] = db.PreStatus
.Select (c => c.NumCoefficientFix)
.FirstOrDefault (c => c.LkpNameFox == "1");
If NumCoefficientFix is a nullable type, then use the ?? operator to convert the null into 0:
ViewData["Fix"] = db.PreStatus
.Select (c => c.NumCoefficientFix)
.FirstOrDefault (c => c.LkpNameFox == "1") ?? 0;
Selecting the NumCoefficientFix first is also (slightly) more efficient for LINQ-to-database queries, in that the SQL generated will select only that column.
You just have to select your NumCoefficientFix property before calling FirstOrDefault:
ViewData["Fix"] = db.PreStatusViws
.Where(c => c.LkpNameFix == "1")
.Select(c => c.NumCoefficientFix)
.FirstOrDefault();`
Or in LINQ notation:
ViewData["Fix"] = (from c in db.PreStatusViws
where c.LkpNameFix == "1"
select c.NumCoefficientFix
).FirstOrDefault();

Resources