Filtering models with pagination only filters first page - rails 3 - ruby

I have a model which I am filtering based on some parameters given by the user. The filtering works just fine but once
I start using pagination, only the records from the first page are filtered and the others are ignored.
This is my code in the controller for filtering:
#start_date = params[:start_date]
#registers = Register.all.order("payment_date DESC").page(params[:page]).per(params[:all] ? nil : Kaminari.config.default_per_page)
#registers.delete_if { |r| !(r.payment_date <= #end_date && r.payment_date >= #start_date) if (#start_date.present? && #end_date.present?) }
And in the view I use <%= paginate #registers %> to paginate the list.

Like #Raffael mentioned in a comment above, I had to use #registers = #registers.where(..) instead of #registers.delete_if(..) because it "screws your page numbers up".

Related

Laravel query builder search by status

In my project, the user can filter the data according to 3 criteria (declared, in progress, finished).
I pass string, in the url parameters [-1,0,1], in order to obtain the active filters. the statuses are defined according to several data coming from different columns of the database, in other words the information is not stored raw in the database.
How can I retrieve filtered data using Query Builder?
$ret = array_filter(explode(',',', $args), 'is_numeric');
$declared = in_array(1, $ret);
$progress = in_array(-1, $ret);
finished = in_array(0, $ret);
if ($declared == false && $progress == false && $finished == false) {
// do the treatment for this case....
}
If I have to deal with all the cases like that, I don't think it's very optimized.
Do you have an idea?
If I understand correctly you have a url like this /your-link?status=n, where n is an int from -1 to 1.
Now, in your controller you can do something like this:
public function yourFunction(Request $request)
{
if (in_array($request['status'], [-1, 0, 1])) {
$data = DB::table('your-table')->where('status', $request['status'])->get();
}
}
I'd recommend you to take a look at pipelines and try to use them with Eloquent or Query builder.
Check out this tutorial and see for yourself how you can implement a solution.

Kaminari combine two collections and place heading in between

I have a page with two collections of items.
def index
#collection1 = Model.collection1
#collection2 = Model.collection2
end
I'm aware of how to combine them together to paginate with Kaminari, however I need to place a <h1>collection 2</h1> header before the items of #collection2 starts (if any).
The page would be something like this:
..Item from collection 1..
..Item from collection 1..
..Item from collection 1..
<h1>collection 2</h1>
..Item from collection 2..
..Item from collection 2..
Im having a hard time figuring out a way to do this. Any idea?
I have come up with the following solution.
def index
#collection1 = Model.collection1
#collection2 = Model.collection2
#collection1_paginated = #collection1.page(params[:page])
#collection2_paginated = Kaminari.paginate_array(#collection1 + #collection2).page(params[:page])
.padding(#collection1_paginated.size)
.take(#collection1_paginated.limit_value - #collection1_paginated.size)
#collection1_or_collection2 = Kaminari.paginate_array(#collection1 + #collection2).page(params[:page])
end
And in the views you can do:
= render partial: 'model', collection: #collection1_paginated
- display_collection_2_heading?
h1 collection 2
= render partial: 'model', collection: #collection2_paginated
= paginate #collection1_or_collection2
To display the Collection 2 heading create the following helper.
def display_collection_2_heading?
#collection1.present? && ((#collection1.count / #collection1_paginated.limit_value)+1) == #collection1_paginated.current_page
end
This helpers makes sure the heading only goes one only time after the last item from #collection1.

SilverStripe 3: Loop greatgrandchildren pages WITH OUT grouping by parent

In my template I'm looping my child pages as 2 separate lists and then their grandchild pages under these. But I want these greatgrandchild pages to be sorted as an entire list and not divided / grouped by their parents.
Simply loop after loop does not work as all greatgrandchild pages should be put in order and not grouped by parent then sorted.
I know this could be done by a function to get all the greatgrandchildpages and sort them by a chosen method (e.g. alphabetically). But I don't want to get ALL of them as I need them just the grandchildren for each child.
PAGE - to show list
Child - List Heading
GrandChild - not shown in list
GreatGrandChild - Listed and ALL sorted Alphabetically
On Page you can get the IDs of all children (which are parents of the grand children) using getIDList():
$ids = Page::get()->filter(array('ParentID' => $this->ID))->getIDList();
Now you can get all Pages (or whatever pagetype you want) by ParentID:
$grandChildren = Page::get()->filter(array('ParentID' => $ids));
Same for grand-grandchildren....
$grandGrandChildren = Page::get()->filter(array('ParentID' => $grandChildren->getIDList()));
You can sort this DataList by whatever you want, e.g.
$sortedgrandGrandChildren = $grandGrandChildren->sort('Title', 'ASC');
edit:
$this->Children() does return an ArrayList, not a DataList, so we have to get all children manually. Be aware, this doesn't respect canView(), so we get all pages, if the current user has permissions or not. For a simple website this should be ok.
Using $this->Children()->column('ID') you get the filtered result.
A ready to use method could be:
public function getGrandGrandChildren() {
$ids = Page::get()->filter(array('ParentID' => $this->ID))->getIDList();
$grandChildren = Page::get()->filter(array('ParentID' => $ids));
$grandGrandChildren = Page::get()->filter(array('ParentID' => $grandChildren->getIDList()));
return $grandGrandChildren->sort('Title', 'ASC');
}
And in your template:
<% loop $GrandGrandChildren %>
$Title
//do whatever you want
<% end_loop %>
SiteTree::get()->filter('ParentID',SiteTree::get()->filter('ParentID',$this->Children()->column('ID')))->filterByCallback(function($page){return $page->canView()})

Django endless pagination with a request.method == 'POST'?

I'm trying to get Django Endless pagination to work on a search form.
All the examples and tutorials I've seen online show how to do it with a simple .all() queryset, but I need to filter out by the search results that I've had in the POST.
Here's how my view looks like for now:
#page_template("core/search_box.html")
def search(request,template = "core/search.html",page_template = "core/search_box.html",extra_context = None):
if request.is_ajax():
#template=page_template()
#users = Skill_User.objects.filter(skill__name__icontains=content).order_by('-level')
#return render_to_response( template , {'page_template': page_template,'menu_home_active':True, 'form':search_form, 'result':users} , context_instance )
return HttpResponse("AJAX")
elif request.method == 'POST':
search_form = SearchForm( request.POST )
# If Form is Valid
if search_form.is_valid():
type = search_form.cleaned_data['type']
content = search_form.cleaned_data['content']
print 'CONTENT ' + str(content)
if (type == 'O'):
users = Skill_User.objects.filter(skill__name__icontains=content).order_by('-level')
elif (type == 'G'):
users= {}
return render_to_response( template , {'page_template': page_template,'menu_home_active':True, 'form':search_form, 'result':users} , context_instance=RequestContext(request) )
else:
return HttpResponse("NOT OK")
So the search is done on POST. But how can I pass this search POST thingy to the ajax query that's done by the endless-pagination plug-in ? I commented out everything in the request.ajax() part, I just need "users" to be filled by the same data as after the POST request. Basically, for now when I scroll down I have "AJAX" showing up, and I'd like the rest of my query as well.
Any ideas? I haven't found anything obvious online about that. I come from a PHP background, and I would think about $_SESSION[] variables. Is there something similar in Django?
Ok, it's doable with a simple request.session[""] object.

Counting results from a search string MVC 3?

I am using MVC3 and have done a search facility in my controller.I have used the model first approach , what I want to be able to allow the user to search for results that contain the given keyword(s) in the data.
If there are no matches to the search term then display an appropriate message.
If there are matching stories:
Display a message like “7 items match your search criteria: 'XXXXX'”
Any help would be much appreciated , Thanks
would it be something like this but with use of the ViewBag to display a message?.
if (!String.IsNullOrEmpty(SearchString))
News = News.Where(s => s.Headline.Count(SearchString));
}
You need to use string.Contains for partial string matching:
var matchingResults = News.Where(s => s.Headline.Contains(searchString));
int count = matchingResults.Count();
if(count == 0)
{
//no matches
}
else
{
//display message
}

Resources