-
-
Notifications
You must be signed in to change notification settings - Fork 815
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
How to add NULL LAST to sorts #443
Comments
Hi @justin808, you could do it with something like this: controller#index
@admin_posts = @q.result.except(:order).order("#{@q.sorts.first} NULLS LAST") I have a longer method called Perhaps we could come up with an API for allowing specifying custom queries like |
@jonatack That syntax does not work for the latest ransack, although I don't know what @q is for sure. This prints out an object reference:
I'm guessing that it's what I have as @search: Here's what I have: class Manager::IndexPresenter
def initialize(q, page, exclude_null_aum)
# ransack conflicts with pagination if no query and going to page 2
if q.present? && q.is_a?(Hash) && (q.values.all? { |v| v.blank? })
q = nil
end
@q = q
@page = page
@exclude_null_aum = exclude_null_aum
end
def search
@search ||= begin
rel = Manager.joins(:most_recent_form_adv).where(simulated: false).
by_filed_at_within_one_year
rel = rel.where.not(form_advs: { aum: nil}) if @exclude_null_aum
search = rel.search(@q)
search.sorts = 'most_recent_form_adv_aum desc' if search.sorts.empty?
search
end
end
def managers
@managers ||= @search.result.page @page
end |
Sorry, I've given this same reply several times here in Ransack issues, I meant to write:
In the Rails console, if you type If you have further questions, have a look at the Ransack source code in |
P.S. With |
Hi @jonatack, thanks for the help. @search.sorts.first.name yields this query:
The problem is that the sort column is really the ransack alias for the joined column. Join is on "most_recent_form_adv". Column to sort on join table is "aum". So I had to do this, using
|
Interesting info with |
I'd agree that this feature at least should be documented, and an API would be better. I'm not familiar enough with Ransack to comment right now. I inherited the Ransack code from another developer. |
@justin808 it worked for me also with attr_name. Thank you! |
Please see this new blog post by @radar, our co-maintainer: http://ryanbigg.com/2015/11/open-source-work/ This is free, DIY, OSS software that no one is paid to work on, yet many companies and people use it. The issue tracker is not for feature requests or personal support. It is for reporting bugs. If there was "progress" on this feature request, you would see it here. If the feature is important to you, contribute a PR or pay someone to do it. Please do not request progress on feature requests without doing anything, because it wastes people's time and makes maintainers want to quit. Maintainers are short of time to test and fix issues and look at PRs. New features are not a priority. If you want them, roll up your sleeves and contribute them, remembering that the maintainer has to maintain them afterward for free in their spare time. Sorry for ranting, this is a result of many small things adding up and not just this one, and thank you for your understanding. |
The solution given by @jonatack does not work if the sort column is an association (in my case a self association). I got it working with the following code for Postgresql: search = Model.ransack(…)
…
result = search.result
orders = result.orders.map { |order| order.direction == :asc ? "#{order.to_sql} NULLS FIRST" : "#{order.to_sql} NULLS LAST" }
result = result.except(:order).order(orders.join(", ")) if orders.count > 0 Hope this helps, cheers. |
This is a very old issue but it showed up in my search results when trying to implement this so I figured I'd put a nicer solution here. From the README you can see instructions for creating a virtual field to sort on, so if you wanted to sort on an attribute called "name" you could do: In your model: scope :sort_by_name_nulls_last_asc, -> { order("name ASC NULLS LAST") }
scope :sort_by_name_nulls_last_desc, -> { order("name DESC NULLS LAST") } in your view: <th><%= sort_link(@q, :name_nulls_last, "Name") %></th> |
One issue I found recently is this. If I do this in the controller, the direction is always
|
This solution is working. You saved my day. Thanks a lot. |
I am having this same issue. Does anyone know the solution to this? |
@andrewdesmondm this isn't ideal, but you can apply nulls last by doing a
|
Just for the others who might visit this page again, you can add the option for postgres so it puts the nulls either first or last. Link to code is: Also you can find the options here:
So, you can change the config file to change the behaviour of ransack within your app (initializers/ransack.rb): Ransack.configure do |config|
config.postgres_fields_sort_option = :nulls_first # :nulls_last, :null_always_first, :null_always_last
end |
Edge case with associations. You would be tempted to use this : # in model
class MyModel < ApplicationRecord
has_one :my_association
end
class MyAssociation < ApplicationRecord
belongs_to :my_model
scope :sort_by_name_nulls_last_asc, -> { order("name ASC NULLS LAST") }
scope :sort_by_name_nulls_last_desc, -> { order("name DESC NULLS LAST") }
end
# in view
<th><%= sort_link(@q, :my_model_my_association_name_nulls_last, "Name") %></th> This will not work. The reason is ransack does not go through associations when trying to get custom ordering scopes. You can find the relevant code here (note the ransack/lib/ransack/visitor.rb Lines 57 to 68 in cc624b9
It first tries to validate that we have an attribute whose name is valid and since it receives You can hack your way through it with something along those lines : # in model
class MyModel < ApplicationRecord
has_one :my_association
scope :sort_by_my_association_name_nulls_last_asc, -> { joins(:my_association).order("my_association.name ASC NULLS LAST")
scope :sort_by_my_association_name_nulls_last_desc, -> { joins(:my_association).order("my_association.name DESC NULLS LAST")
end
class MyAssociation < ApplicationRecord
belongs_to :my_model
end
# in view
<th><%= sort_link(@q, :my_model_my_association_name_nulls_last, "Name") %></th> On another note the order clause "my_association.name DESC NULLS LAST" was different on my MySQL system. I went with "ISNULL(my_association.name), my_association.name DESC" |
There's no interested to sort with other attributes, keep it short and bug free. Moreover, sort with null last does not work activerecord-hackery/ransack#443 (comment)
I need NULL results to go last.
This is simple to do in a SQL statement. Just list "NULL LAST" right after the order predicate.
Where is the right place to put this?
Also, in the code for evaluate, I don't think relation.except(:order) is necessary, as the reorder takes care of removing the old order.
The text was updated successfully, but these errors were encountered: