I am making a search form with in the JqueryUI tabs. The tab contains the Ajax search form and a table showing the results from the search. Also I have used IpagedList to page through the result table.The Index action of the controller contains the Linq query and controls which view to render. Following is the code for Index action:
public ActionResult Index(ConsultantSearch model, int page = 1)
{
if (!String.IsNullOrEmpty(model.SearchButton) ||!String.IsNullOrEmpty(model.CancelButton))
{
var consultants = from con in db.Consultants
where (model.ConsultantName == null || con.ConsultantName.Contains(model.ConsultantName)) && (model.CompanyID == null || con.CompanyID == model.CompanyID)
&& (model.ClientID == null || con.ClientID == model.ClientID) && (model.VendorID == null || con.VendorID == model.VendorID) && (model.RecruiterID == null || con.RecruiterID == model.RecruiterID)
&& (model.Class == null || con.Class == model.Class) && (model.W2_1099 == null || con.W2_1099 == model.W2_1099) && (model.IsActive == null || con.IsActive == model.IsActive)
&& (model.StartDate == null || model.EndDate == null || (con.StartDate >= model.StartDate && con.EndDate <= model.EndDate))&&( model.StartDate == null || con.StartDate >= model.StartDate) && (model.EndDate == null|| con.EndDate <= model.EndDate)
select con;
consultants = consultants.Include(c => c.Client).Include(c => c.Company).Include(c => c.Recruiter).Include(c => c.SalesPerson).Include(c => c.Vendor);
return PartialView("_ConsultantList",consultants.ToList().ToPagedList(page,RecordsPerPage));
}
else
{
var consultants = db.Consultants.Include(c => c.Client).Include(c => c.Company).Include(c => c.Recruiter).Include(c => c.SalesPerson).Include(c => c.Vendor);
return PartialView(consultants.ToList().ToPagedList(page, RecordsPerPage));
}
}
When the user first loads the page the else part executes which renders the partial view Index which shows the form and the table showing all consultants currently in Database. However when the search button or cancel button is clicked the if condition gets true and the partial view Consultant list is rendered. Which updates only the result table part of the page.
Now my question is I want to add a condition in which when the paging control is used the If condition gets true and only the next page of consultant records in the result table are shown. I can use isAjaxRequest() in the If condition. But the problem is when the JqueryUI tab (containing the from and table) will load the If condition will become true because of the isAjaxRequest() and only Consultant List view will be rendered which I do not want.
So basically I want to differentiate between the two ajax requests..If the ajax request is for the tabs then the else condition should work and if it is from paging then the if condition should work.
Any ideas...?
Redesign your controller action method. Instead of placing conditional logic in your controller add an action method for each condition you need to satisfy and put the logic of which one to request in the view/markup.
The best way to tell if you should load your consultant grid or a paged view of some search results is if the view/JavaScript performs an ajax request to the appropriate action method.
Related
So I have a drivers (user table) which has a relationship with the subscriptions table. There are 3 different tiers available: Gold, Silver and a Free tier. What i want to do is group and order by tiers, so I'd have the golds together, silvers together etc in descending order.
What i have now in my controller:
class DriversController < ApplicationController
def index
order_subs = Driver.order_by_subs.all
def gold_drivers
Driver.select { |driver| driver.subscriptions.stripe_plan == 'price_xxx' || driver.subscriptions.stripe_plan == 'price_xxx'}
end
def silver_drivers
Driver.select { |driver| driver.subscriptions.stripe_plan == 'price_xxx' || driver.subscriptions.stripe_plan == 'price_xxx'}
end
def free_drivers
Driver.select { |driver| driver.subscriptions == 'null' || driver.subscriptions == ''}
end
#pagy, #drivers = pagy(
Driver.joins(:profile).select(
'drivers.*',
'(profiles.no_races + profiles.no_poles + profiles.no_podiums + profiles.no_wins) AS score'
).reorder(gold_drivers, silver_drivers, free_drivers, score),
page: params[:page],
items: 16
)
end
end
So my thoughts were I could select the records under a variable i.e gold_drivers and then add them as I would in the reorder section in the #pagy pagination section .reorder(gold_drivers, silver_drivers, free_drivers, score) At the moment when i run the page I get the error undefined method stripe_plan' for nil:NilClass` so i'm guessing it can't find the column. If it's a free user, they won't have a record in the subscription table. Thanks
EDIT: driver model
scope :is_gold, -> { where("drivers.subscriptions.stripe_plan == 'price_xxx'") || where("drivers.subscriptions.stripe_plan == 'price_xxx'") }
scope :is_silver, -> { where("drivers.subscriptions.stripe_plan == 'price_xxx'") || where("drivers.subscriptions.stripe_plan == 'price_xxx'") }
scope :is_null, -> { where("drivers.subscriptions.stripe_plan == ''") || where("drivers.subscriptions.stripe_plan" == null) }
scope :order_by_subs, -> { reorder(:is_gold, :is_silver, :is_null) }
I have to be honest your code is incredibly confusing. It looks like you can order by subs, but I guess you can't, I'm not sure what is working and what isn't looking at your code. I see what you are doing from our previous conversation and this is off. Like I said in my comment, I would focus on understanding the basics here before you dive into some of this stuff. I'm going to fix your method and explain along the way so it hopefully makes some more sense and either works, or shows you a path to getting it to work.
class DriversController < ApplicationController
def index
# because there is no # on this it is a local variable, it will not be available in the view. Wondering also why you didn't just use this for the select below. Also, if you can already order by subs why would you even need to select them, wasn't that the reason for selecting them like this in the first place?
order_subs = Driver.order_by_subs.all
# it is my understanding you want these in the view so we add the # symbol which makes it an instance variable and you access those variables in the view now
#gold_drivers = order_subs.select { |driver| driver.subscriptions.stripe_plan == 'price_xxx' || driver.subscriptions.stripe_plan == 'price_xxx'}
#silver_drivers = order_subs.select { |driver| driver.subscriptions.stripe_plan == 'price_xxx' || driver.subscriptions.stripe_plan == 'price_xxx'}
#free_drivers = order_subs.select { |driver| driver.subscriptions == 'null' || driver.subscriptions == ''}
# Not sure where your local variable 'score' is coming from, do you need to set that first?
#pagy, #drivers = pagy(
Driver.joins(:profile).select(
'drivers.*',
'(profiles.no_races + profiles.no_poles + profiles.no_podiums + profiles.no_wins) AS score'
).reorder(#gold_drivers, #silver_drivers, #free_drivers, score),
page: params[:page],
items: 16
)
end
end
O.k so now you are setting the drivers values as instance variables which can be accessed in your view.
I'm running the query below to obtain all the events (as a registered student) I'm attending on a specific day and getting an error that says
System.NotSupportedException: Unable to create a constant value of type 'YogaBandy.Models.Profile.YogaProfile'. Only primitive types or enumeration types are supported in this context.
Here is the query I'm using to get all events I'm regsitered for on a specific day.
// my profile
var yogaProfile = dbContext.YogaProfiles.Where(i => i.ApplicationUserId == userId).First();
// events I'm registered for on a specific day
var eventsNew = dbContext.YogaSpaceEvents.Where(
i => i.EventDateTime.Day == date.Day
&& i.EventStatus == YogaSpaceEventStatus.Active
&& i.RegisteredStudentsNew.Contains(yogaProfile)).ToList();
I think it might have something to do with part, but not sure
&& i.RegisteredStudentsNew.Contains(yogaProfile)
FYI - my RegisteredStudentsNew looks like this in the 'YogaSpaceEvents' entity
public virtual ICollection<YogaProfile> RegisteredStudentsNew { get; set; }
and when I add a newly regsitered student I add him/her like this
spaceEvent.RegisteredStudentsNew.Add(yogaProfile);
dbContext.SaveChanges();
Try to move your YogaProfiles.Where(i => i.ApplicationUserId == userId) inside Include statement.
Example:
var eventsNew = dbContext.YogaSpaceEvents
.Include(p=>p.RegisteredStudentsNew.Where(rp => rp.ApplicationUserId == userId))
.Where( i => i.EventDateTime.Day == date.Day
&& i.EventStatus == YogaSpaceEventStatus.Active)
.ToList();
OR
use Any in your where clause
var eventsNew = dbContext.YogaSpaceEvents
.Include(p=>p.RegisteredStudentsNew)
.Where(i => i.EventDateTime.Day == date.Day
&& i.EventStatus == YogaSpaceEventStatus.Active
&& i.RegisteredStudentsNew.Any(rp => rp.ApplicationUserId == userId))
.ToList();
Please read this for why use Include in LINQ.
So I'm making authorization from scratch based on Ryan Bates' railscast.
I figured the problem i'm facing is in this part of code
action == 'create' || action == 'update'
What I want to say is that if the action is create OR action is update (so either of them) AND obj.has_accepted_acceptance? it should return false, but it returns true unless I eliminate || action == 'update' part of code. only then it works as intended.
So is the problem with the operators?
Thank you in advance for your time!
class Permission < Struct.new(:user)
def allow?(controller, action, obj = nil)
if controller == "acceptances"
if action == 'create' || action == 'update' && obj.has_accepted_acceptance?
return false
end
end
return true
end
end
Try grouping your conditions:
if (action == 'create' || action == 'update') && obj.has_accepted_acceptance?
You can use the ActiveSupport .in? to convert the first from two clauses to one:
if action.in?(%w[create update]) && obj.has_accepted_acceptance?
The same in plain old ruby would be:
if %w[create update].includes?(action) && obj.has_accepted_acceptance?
Here is what I currently have:
#Model.TPGForumTopicQuery.Select(m => m.closed != true && m.deleted != true)
.Where(m => m.TPGForumBoardID == item.boardID).Count()
This returns an odd error:
An error occurred during the compilation of a resource required to service this request.
Please review the following specific error details and modify your source code appropriately.
If I remove the .Select it works without error and counts all of the topics under the forum board. But the topics can be marked 'closed' or 'active' and I need to omit those in the count.
The above code is within a #foreach loop. So item.boardID is talking about the Forum Board.
Do not do the filter in the Select. Do it in the Where:
#Model.TPGForumTopicQuery.Where(m => m.TPGForumBoardID == item.boardID && m.closed != true && m.deleted != true).Count()
A bit of optimization:
Rather than m.closed != true, do !m.closed
#Model.TPGForumTopicQuery.Where(m => m.TPGForumBoardID == item.boardID && !m.closed && !m.deleted).Count()
And rather than get the Count after the Where-clause, you can pass in the where-clause to the Count():
#Model.TPGForumTopicQuery.Count(m => m.TPGForumBoardID == item.boardID && !m.closed && !m.deleted)
I am developing MVC app and I am using the LINQ in controller.
I am trying to get one rechord with below query, but its giving an error...
Approval oAP = new Approval();
oAP = db.Approvals.Where(e => (e.ApprovedBy.Id == loggedEmployee.Id) && (e.ReviewNo == oPaymentAdvice.ReviewCount));
Is there any wrong syntax ?
Got the answer
oAP = db.Approvals.Where(e => (e.ApprovedBy.Id == loggedEmployee.Id) && (e.ReviewNo == oPaymentAdvice.ReviewCount)).FirstOrDefault();
Change this
e.ApprovedBy.Id = loggedEmployee.Id
For
e.ApprovedBy.Id == loggedEmployee.Id
You're comparing not assigning values.
Also you may add this
oAP = db.Approvals.Where(e => (e.ApprovedBy.Id == loggedEmployee.Id) && (e.ReviewNo == oPaymentAdvice.ReviewCount)).FirstOrDefault();
Because i'm assuming that you want to return only one
Some remarks:
You should be able to drop the Where:
oAP = db.Approvals.FirstOrDefault(e => (e.ApprovedBy.Id == loggedEmployee.Id) && (e.ReviewNo == oPaymentAdvice.ReviewCount));
Personally, I try to avoid the First and FirstOrDefault functions, because if you know there is only one record and if you want to enforce this, you can use SingleOrDefault:
oAP = db.Approvals.SingleOrDefault(e => (e.ApprovedBy.Id == loggedEmployee.Id) && (e.ReviewNo == oPaymentAdvice.ReviewCount));
If you know there will always be (more than) one record, you can drop the 'OrDefault' part and use First() or Single().