Open hovancik opened 8 years ago
Hi @hovancik,
I assume that you have a User
model with a language
bitwise attribute ;)
here is the "SQL-way" :
class User
include AttrBitwise
attr_bitwise :languages,
column_name: 'languages_value',
mapping: [:fr, :en, :ca]
scope :with_any_languages, lambda { |*types_sym|
where(languages_value: bitwise_union(*types_sym, 'languages'))
}
scope :with_all_languages, lambda { |*types_sym|
where(languages_value: bitwise_intersection(*types_sym, 'languages'))
}
end
then, you can do :
# return all users who can see at least english and french content
users = User.with_any_languages(:fr, :en)
and the "Ruby way" :
class User
include AttrBitwise
attr_bitwise :languages,
column_name: 'languages_value',
mapping: [:fr, :en, :es]
def any_languages?(*type_syms)
type_syms.any? do |type_sym|
language?(type_sym)
end
end
def all_languages?(*type_syms)
type_syms.all? do |type_sym|
language?(type_sym)
end
end
end
then you can do :
# return all users who can see at least english and french content
users = User.any_languages?(:fr, :en)
I don't have any examples for negation for now.
Cheers,
@wittydeveloper hi, I was using example from Readme. I was trying some queries and I could't get to understand how it works. After your answer I think I understand, but not sure, as I am getting some weird stuff.
So here is what I am doing
ruby 2.3.0p0
, attr_bitwise (0.0.4)
, Rails 4.2.6
class Customer < ActiveRecord::Base
include AttrBitwise
attr_bitwise :trust_level, mapping: %i{
view_prices make_order cash_on_delivery pay_by_invoice mixit_delivery
}
scope :with_any_trust_levels, lambda { |*trust_levels_sym|
where(trust_level_value: bitwise_union(*trust_levels_sym, 'trust_level'))
}
scope :with_all_trust_levels, lambda { |*trust_levels_sym|
where(trust_level_value: bitwise_intersection(*trust_levels_sym, 'trust_level'))
}
end
I am picking all possible trust_levels
Customer.first.trust_level_value
=> 31
Some queries and whether they are OK in my understanding:
Legit:
Customer.with_all_trust_levels(:make_order, :view_prices, :cash_on_delivery, :pay_by_invoice, :mixit_delivery)
Customer Load (0.5ms) SELECT "customers".* FROM "customers" WHERE "customers"."trust_level_value" = 31
#<ActiveRecord::Relation [#<Customer id: 1,
Legit:
Customer.with_all_trust_levels(:make_order, :view_prices, :cash_on_delivery, :pay_by_invoice)
Customer Load (0.5ms) SELECT "customers".* FROM "customers" WHERE "customers"."trust_level_value" IN (15, 31)
#<ActiveRecord::Relation [#<Customer id: 1,
Not legit? :
Customer.with_all_trust_levels(:make_order, :view_prices, :cash_on_delivery)
Customer Load (0.4ms) SELECT "customers".* FROM "customers" WHERE "customers"."trust_level_value" IN (7, 15, 23)
=> #<ActiveRecord::Relation []>
Customer.with_all_trust_levels(:make_order, :view_prices)
Customer Load (0.4ms) SELECT "customers".* FROM "customers" WHERE "customers"."trust_level_value" IN (3, 7, 11, 19)
=> #<ActiveRecord::Relation []>
Customer.with_all_trust_levels(:make_order)
Customer Load (0.4ms) SELECT "customers".* FROM "customers" WHERE "customers"."trust_level_value" IN (3, 2, 6, 10, 18)
=> #<ActiveRecord::Relation []>
And here, only first 3
Customer.first.trust_level_value
=> 7
ok:
2.3.0 :074 > Customer.with_all_trust_levels(:make_order, :view_prices, :cash_on_delivery, :pay_by_invoice, :mixit_delivery)
Customer Load (0.5ms) SELECT "customers".* FROM "customers" WHERE "customers"."trust_level_value" = 31
=> #<ActiveRecord::Relation []>
2.3.0 :075 > Customer.with_all_trust_levels(:make_order, :view_prices, :cash_on_delivery, :pay_by_invoice)
Customer Load (0.4ms) SELECT "customers".* FROM "customers" WHERE "customers"."trust_level_value" IN (15, 31)
=> #<ActiveRecord::Relation []>
2.3.0 :077 > Customer.with_all_trust_levels(:make_order, :view_prices, :cash_on_delivery)
Customer Load (0.4ms) SELECT "customers".* FROM "customers" WHERE "customers"."trust_level_value" IN (7, 15, 23)
=> #<ActiveRecord::Relation [#<Customer id: 1]>
2.3.0 :078 > Customer.with_all_trust_levels(:make_order, :view_prices)
Customer Load (0.4ms) SELECT "customers".* FROM "customers" WHERE "customers"."trust_level_value" IN (3, 7, 11, 19)
=> #<ActiveRecord::Relation [#<Customer id: 1]>
not ok?
2.3.0 :079 > Customer.with_all_trust_levels(:make_order)
Customer Load (0.4ms) SELECT "customers".* FROM "customers" WHERE "customers"."trust_level_value" IN (3, 2, 6, 10, 18)
=> #<ActiveRecord::Relation []>
do I understand that correctly?
and here is example when I use any
.
Customer.first.trust_level
Customer Load (0.4ms) SELECT "customers".* FROM "customers" ORDER BY "customers"."id" ASC LIMIT 1
=> [:view_prices, :make_order, :cash_on_delivery]
2.3.0 :081 > Customer.first.trust_level_value
Customer Load (0.4ms) SELECT "customers".* FROM "customers" ORDER BY "customers"."id" ASC LIMIT 1
=> 7
2.3.0 :082 > Customer.with_any_trust_levels(:make_order)
Customer Load (0.4ms) SELECT "customers".* FROM "customers" WHERE "customers"."trust_level_value" IN (3, 2, 6, 10, 18)
=> #<ActiveRecord::Relation []>
2.3.0 :083 > Customer.with_any_trust_levels(:make_order)
Customer Load (0.4ms) SELECT "customers".* FROM "customers" WHERE "customers"."trust_level_value" IN (3, 2, 6, 10, 18)
=> #<ActiveRecord::Relation []>
2.3.0 :084 > Customer.with_any_trust_levels(:make_order, :view_prices)
Customer Load (0.4ms) SELECT "customers".* FROM "customers" WHERE "customers"."trust_level_value" IN (3, 2, 6, 10, 18, 1, 5, 9, 17)
=> #<ActiveRecord::Relation []>
2.3.0 :085 > Customer.with_any_trust_levels(:make_order, :view_prices,:cash_on_delivery)
Customer Load (0.4ms) SELECT "customers".* FROM "customers" WHERE "customers"."trust_level_value" IN (3, 2, 6, 10, 18, 1, 5, 9, 17, 4, 12, 20)
=> #<ActiveRecord::Relation []>
2.3.0 :086 > Customer.with_any_trust_levels(:make_order, :view_prices,:cash_on_delivery,:pay_by_invoice)
Customer Load (0.4ms) SELECT "customers".* FROM "customers" WHERE "customers"."trust_level_value" IN (3, 2, 6, 10, 18, 1, 5, 9, 17, 4, 12, 20, 8, 24)
=> #<ActiveRecord::Relation []>
2.3.0 :087 > Customer.with_any_trust_levels(:make_order, :view_prices,:cash_on_delivery,:pay_by_invoice,:mixit_delivery)
Customer Load (0.4ms) SELECT "customers".* FROM "customers" WHERE "customers"."trust_level_value" IN (3, 2, 6, 10, 18, 1, 5, 9, 17, 4, 12, 20, 8, 24, 16)
=> #<ActiveRecord::Relation []>
How would I go about
return all users who can see at least english and french content
user 1 =>
en
,fr
,ca
user 2 =>en
,fr
user 3 =>en
I wanna query users with both
en
andfr
, so I wanna get user 1 and user 2also nice would be opposite: users that do not have them.