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.
Related
I'm trying to understand how to use the select method in queries to return custom columns.
I'm running Rails 5.2, database is postgresql.
m = Message.all.select("messages.*, CASE WHEN id > 30 THEN TRUE ELSE FALSE END AS above_30")
returns only the messages table with all its columns. How do I get the above_30 column, preferable eager loaded?
The above_30 is there, but Rails will not define an access for it because there is no column by that name in your schema.
You can define one yourself, or use m[:above_30] to access the "raw" attributes of the object as returned from the query.
I am trying to use distinct on in rails with a scope, I've created a method in my model like this:
def self.fetch_most_recent_by_user(scope)
scope.where(guid: scope.except(:select).select("DISTINCT ON (eld_logs.user_id) user_id, eld_logs.guid").order("user_id, eld_logs.created_at desc").map(&:guid))
end
When I execute this I get and error like:
TestModel.fetch_most_recent_by_user(TestModel.includes(:user))
ERROR: syntax error at or near "DISTINCT"
LINE 1: SELECT guid, DISTINCT ON (user_id) user_id...
On searching on DISTINCT ON I found out that it should be the first element in a select statement for postgres to make it work.
I want to prepend the DISTINCT ON in the select statement. I have tried clearing the old select statements using except(:select) which I got from here, but it doesn't work because the includes(:user) prepends users attributes first while doing a left join.
I am using Rails 4.0.13 and Postgres 9.4.12. Any help is appreciated.
I found that if the includes was meddling with the distinct my sub query, because which DISTINCT ON failed. I modified my method to this and it works:
def self.fetch_most_recent_eld_log_by_user(scope, include_associations = { })
scope.where(guid: scope.except(:select).select("DISTINCT ON (eld_logs.user_id) eld_logs.user_id, eld_logs.guid").order("eld_logs.user_id, eld_logs.created_at desc").map(&:guid))
.includes(include_associations)
end
Still it'll be good if someone can provide a way to prepend something in the select statement of active record scope.
I'm trying to implement auto complete for Rails. I have something like the following in my code -
Location.where("name like ?", "%#{params[:location]}%")
I'm afraid this would lead to SQL injection. Something like the following -
SELECT * FROM Locations WHERE (name LIKE '%green%') OR 1=1--%'
When params[:location] is something like this green%') OR 1=1--
Is there any way, I can avoid SQLi for substring based search in Rails?
Dave is right. Try it and see what it outputs. It wraps the whole thing up as part of the condition. In my Courses model.
> x = "'') OR SELECT * FROM Users"
=> "'') OR SELECT * FROM Users"
> Course.where(["name like ?", "%#{x}%"])
Course Load (38.7ms) SELECT "courses".* FROM "courses" WHERE
(name like '%'''') OR SELECT * FROM Users%')
=> []
If you're using Postgres, I would suggest using trigram support in Postgres to do this.
Throw this in a migration to get things set up:
CREATE EXTENSION pg_trgm;
then run your query like this:
Location.select('*', "similarity(search_term, #{ActiveRecord::Base.sanitize(search_term)}) AS similarity").order('similarity DESC, search_term')
or, just do what you're doing but wrap the param in #{ActiveRecord::Base.sanitize(search_term)}
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?
I'm using ruby 1.9.2 and rails 3 with a postgresql 8.4 database.
I have the following piece of rails code.
#playersonline = Member.find(:all, :conditions => ["loggedIn = ?", true] )
And I get the following error when the line is encountered:
PGError: ERROR: column "loggedin" does not exist
Looking at the query it generates it shows the following:
SELECT "members".* FROM "members" WHERE (loggedIn = 't')
The loggedIn column does exist in my table, and it has a boolean data type.
Another thing that is odd, when I try to query just the loggedIn column via a sql browser I get the same error? i.e. select loggedIn from members
Thanks
Postgres is case-sensitive by default so loggedIn isn't the same as loggedin. Although you can override it, Rails convention is that variable name-parts are separates by an underscore.
I wouldn't recommend re-inventing the wheel. Go in and change the columnn name (and any other columns that follow your notation) you might have to logged_in. This will prevent you from encountering any more strange errors.