I have ActiveAdmin in my rails app. I was trying to disable default order which ActiveAdmin apply when retrieve records, I've add this to my resource:
config.sort_order = ''
Now when I visit html version of page it properly get the records without order but when I export to csv it retrieves records with order:
SELECT "vw_survey_packs".* FROM "vw_survey_packs" WHERE ("vw_survey_packs"."id" > 22542) ORDER BY "vw_survey_packs"."id" ASC LIMIT 1000
How can I change that?
See this issue on github. Basically: it's not possible without changing the code yourself.
Related
I am trying to find all variants in spree where is_master is false but ransack is not working as expected. The reason I am using ransack is so I can run this search over the spree api so I can make a request like /api/v1/variants?q[is_master_true]='0' to get all the non master variants.
In the documentation
>> User.ransack(awesome_false: '1').result.to_sql
=> SELECT "users".* FROM "users" WHERE ("users"."awesome" = 'f')
In practice
> Spree::Variant.ransack(is_master_false: '1').result.to_sql
=> "SELECT \"spree_variants\".* FROM \"spree_variants\" WHERE \"spree_variants\".\"deleted_at\" IS NULL"
The is_master_false is ignored in the sql
Another search like sku_eq works fine
> Spree::Variant.ransack(sku_eq: '17636').result.to_sql
=> "SELECT \"spree_variants\".* FROM \"spree_variants\" WHERE \"spree_variants\".\"deleted_at\" IS NULL AND \"spree_variants\".\"sku\" = '17636'"
Why does is_master_false: '1' do nothing to the sql query created instead of finding records where is_master = false?
#Qwertie: For ransack search you need to first whitelist all the attributes on which you want to perform ransack search.
Currently, in the Variant model only weight sku are whitelisted.
So you need to whitelist is_master field yourself
For doing just create a decorator for variant in spree/models with name variant_decorator.rb and write
Spree::Variant.class_eval do
### WHITELISTED ATTRIBUTES ###
self.whitelisted_ransackable_attributes |= ['is_master']
end
Or in spree.rb
add Spree::Variant.whitelisted_ransackable_attributes.push('is_master')
Now restart your server or rails console and try it out.
I want to order all the items in a model Item so it displays the most recent ones first. According to the Rails guide, the following code should work:
Item.order("created_at DESC")
However, when I type that (or varieties) in the terminal, the most recent item always shows up last, and that's how they show up on my page. How do I efficiently retrieve them with he most recent first? (I'm going to display only some of them at a time on each page.)
Note that my default scope for items is oldest first.
Update:
This is the SQL I get:
SELECT "comments".* FROM "comments" ORDER BY comments.created_at ASC, created_at DESC
So I guess I shouldn't use default scopes...
The query you posted is correct
Item.order("created_at DESC")
The only reason why it would not work is if there is anything else conflicting with it. In general, the conflict is represented by a default_scope.
If you have a default scope that overrides your order, you should first unscope the query
Item.unscoped { Item.order("created_at DESC") }
If you are using default scopes, I strongly encourage you to avoid them. They are very hard to debug and unscope.
There are very few cases where default scopes make sense. You can simply pass the (default) scope at select time in the controller or create a custom method for it.
I realise this is a really old question, but none of the answers contain the solution without writing raw SQL, which is available since Rails 3+:
Item.order(created_at: :desc)
or using the reverse_order method:
Item.order(:created_at).reverse_order
See more at http://guides.rubyonrails.org/active_record_querying.html#ordering
and
http://guides.rubyonrails.org/active_record_querying.html#reverse-order.
I modified CDub's answer with reverse so it now works:
Item.order(:created_at).reverse
I'm still not sure why the Rails guide's way doesn't work. Also the above method doesn't work well with pagination.
Item.unscoped.order('created_at DESC') should work.Using reverse might decrease the performance when the number of records increases
Correct one and tested
#purchase_orders = current_company.purchase_orders.order(:date)
#purchase_orders = #purchase_orders.reverse_order
you can add You can also define the default order in Item model
default_scope order('created_at DESC')
New to Ruby and Rails so forgive me if my terminology is off a bit.
I am working on optimizing some inherited code and watching the logs I am seeing queries repeat themselves due to lines like this in a .rabl file:
node(:program) { |user| (!user.programs.first.nil?) ? user.programs.first.name : '' }
user and program are both active record objects
Moving to the rails console, I can replicate the problem, but I can also get the expected behavior, which is only one query:
>u = User.find(1234)
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE [...]
> (!u.programs.first.nil?) ? u.programs.first.name : ''
Program Load (0.2ms) SELECT `programs`.* FROM `programs` [...]
Program Load (0.3ms) SELECT `programs`.* FROM `programs` [...]
=> "Output"
Note that repeating the ternary statement in the console will always give me 2 queries.
I can get the expected behavior like so:
> newu = User.find(12345)
User Load (3.8ms) SELECT `users`.* FROM `users` WHERE [...]
> newu.programs
Program Load (0.6ms) SELECT `programs`.* FROM `programs` [...]
> (!newu.programs.first.nil?) ? newu.programs.first.name : ''
=> "Output"
Repeating the ternary statement now won't requery at all.
So the question is: why does calling newu.programs change the behavior? Shouldn't calling u.programs.first.nil? also act to load all the program records in the same way?
With an association, first is not sugar for [0].
If the association is loaded, then it just returns the first element of the array. If it is not loaded, it makes a database query to load just that one element. It can't stick that in the association cache (at least not without being smarter), so the next query to first does the query again (this will use the query cache if turned on)
What Rails is assuming is that if the association is big, and you are only using one element of it then it would be silly to load the whole thing. This can be a little annoying when this isn't the case and you are just using the one item, but you're using it repeatedly.
To avoid this you can either assign the item to a local variable so that you do genuinely only call first once, or do
newu.programs[0]
which will load the whole association (once only) and return the first element.
Rails does the same thing with include?. Instead of loading the whole collection, it will run a query that tests whether a specific item is in the collection (unless the collection is loaded)
I can't find this documented anywhere but here is my problem: when I query via active record and use "only" the "order" clause is ignored. For example I have a Blog model:
Blog.order('id desc')
returns all the blogs with the highest ID first - as expected but:
Blog.order('id desc').only(:id)
returns only the id's (as expected) but the order clause is completely ignored, the smallest id comes first.
I have tested this with Ruby 1.9.3p327 and both Rails 4.0.0.beta1 and Rails 3.2.13 and I get the same results.
Is this a feature or a bug? To me it's a bug because the Rails crew were trumpeting how find_by_sql is not really needed but in this case it is:
Blog.find_by_sql("select id from blogs order by id desc")
which gives the correct answer.
Try using pluck instead of only. only is used to override portions of the previously formed query chain. As the the docs demonstrate:
Post.where('id > 10').limit(20).order('id desc').only(:order, :where)
results in:
SELECT * FROM posts WHERE id > 10 ORDER BY id DESC
This is because the limit modification will be ignored, since the list passed to only doesn't include :limit.
UPDATE
If you need an actual model object returned instead of an array of id's, use select:
Blog.order('id desc').select('id')
I was wondering if there was any way in rails to return a new_attribute in a select as statement in rails.
For simplified example Books.select("'tuds' as new_attribute").first where new_attribute isn't in the DB, just returns a bunch of empty active record objects.
Seems like this should work, but I'm not having any luck. Any thoughts!?
Thanks!
-Mario
`
UPDATE: I'm a goof. I wasn't actually looking at the actual object and was just looking at the log in my console.
Works for me using Rails 3.2:
irb(main):001:0: User.select('full_name as whatever').first.whatever
User Load (0.5ms) SELECT id, full_name as whatever FROM `users` LIMIT 1
=> "Zap Brannigan"
Is this what you want to achieve?