Class: CanCan::ModelAdapters::ActiveRecordAdapter
- Inherits:
-
AbstractAdapter
- Object
- AbstractAdapter
- CanCan::ModelAdapters::ActiveRecordAdapter
- Defined in:
- lib/cancan/model_adapters/active_record_adapter.rb
Direct Known Subclasses
Instance Attribute Summary collapse
-
#compressed_rules ⇒ Object
readonly
Returns the value of attribute compressed_rules.
Attributes inherited from AbstractAdapter
Class Method Summary collapse
-
.nested_subject_matches_conditions?(parent, child, all_conditions) ⇒ Boolean
parent_id condition can be an array of integer or one integer, we check the parent against this.
-
.override_nested_subject_conditions_matching?(parent, child, all_conditions) ⇒ Boolean
When belongs_to parent_id is a condition for a model, we want to check the parent when testing ability for a hash => model.
- .parent_child_conditions(parent, child, all_conditions) ⇒ Object
- .version_greater_or_equal?(version) ⇒ Boolean
- .version_lower?(version) ⇒ Boolean
Instance Method Summary collapse
- #build_relation(*where_conditions) ⇒ Object
-
#conditions ⇒ Object
Returns conditions intended to be used inside a database query.
- #database_records ⇒ Object
- #extract_multiple_conditions(conditions_extractor, rules) ⇒ Object
-
#initialize(model_class, rules) ⇒ ActiveRecordAdapter
constructor
A new instance of ActiveRecordAdapter.
-
#joins ⇒ Object
Returns the associations used in conditions for the :joins option of a search.
Methods inherited from AbstractAdapter
adapter_class, find, for_class?, inherited, matches_condition?, matches_conditions_hash?, override_condition_matching?, override_conditions_hash_matching?
Constructor Details
#initialize(model_class, rules) ⇒ ActiveRecordAdapter
Returns a new instance of ActiveRecordAdapter.
16 17 18 19 20 21 |
# File 'lib/cancan/model_adapters/active_record_adapter.rb', line 16 def initialize(model_class, rules) super @compressed_rules = RulesCompressor.new(@rules.reverse).rules_collapsed.reverse StiNormalizer.normalize(@compressed_rules) ConditionsNormalizer.normalize(model_class, @compressed_rules) end |
Instance Attribute Details
#compressed_rules ⇒ Object (readonly)
Returns the value of attribute compressed_rules.
14 15 16 |
# File 'lib/cancan/model_adapters/active_record_adapter.rb', line 14 def compressed_rules @compressed_rules end |
Class Method Details
.nested_subject_matches_conditions?(parent, child, all_conditions) ⇒ Boolean
parent_id condition can be an array of integer or one integer, we check the parent against this
31 32 33 34 35 36 37 |
# File 'lib/cancan/model_adapters/active_record_adapter.rb', line 31 def nested_subject_matches_conditions?(parent, child, all_conditions) id_condition = parent_child_conditions(parent, child, all_conditions) return id_condition.include?(parent.id) if id_condition.is_a? Array return id_condition == parent.id if id_condition.is_a? Integer false end |
.override_nested_subject_conditions_matching?(parent, child, all_conditions) ⇒ Boolean
When belongs_to parent_id is a condition for a model, we want to check the parent when testing ability for a hash => model
26 27 28 |
# File 'lib/cancan/model_adapters/active_record_adapter.rb', line 26 def override_nested_subject_conditions_matching?(parent, child, all_conditions) parent_child_conditions(parent, child, all_conditions).present? end |
.parent_child_conditions(parent, child, all_conditions) ⇒ Object
39 40 41 42 43 44 45 |
# File 'lib/cancan/model_adapters/active_record_adapter.rb', line 39 def parent_child_conditions(parent, child, all_conditions) child_class = child.is_a?(Class) ? child : child.class foreign_key = child_class.reflect_on_all_associations(:belongs_to).find do |association| association.klass == parent.class end&.foreign_key&.to_sym foreign_key.nil? ? nil : all_conditions[foreign_key] end |
.version_greater_or_equal?(version) ⇒ Boolean
6 7 8 |
# File 'lib/cancan/model_adapters/active_record_adapter.rb', line 6 def self.version_greater_or_equal?(version) Gem::Version.new(ActiveRecord.version).release >= Gem::Version.new(version) end |
.version_lower?(version) ⇒ Boolean
10 11 12 |
# File 'lib/cancan/model_adapters/active_record_adapter.rb', line 10 def self.version_lower?(version) Gem::Version.new(ActiveRecord.version).release < Gem::Version.new(version) end |
Instance Method Details
#build_relation(*where_conditions) ⇒ Object
89 90 91 92 93 94 95 |
# File 'lib/cancan/model_adapters/active_record_adapter.rb', line 89 def build_relation(*where_conditions) relation = @model_class.where(*where_conditions) return relation unless joins.present? # subclasses must implement `build_joins_relation` build_joins_relation(relation, *where_conditions) end |
#conditions ⇒ Object
Returns conditions intended to be used inside a database query. Normally you will not call this method directly, but instead go through ModelAdditions#accessible_by.
If there is only one “can” definition, a hash of conditions will be returned matching the one defined.
can :manage, User, :id => 1
query(:manage, User).conditions # => { :id => 1 }
If there are multiple “can” definitions, a SQL string will be returned to handle complex cases.
can :manage, User, :id => 1
can :manage, User, :manager_id => 1
cannot :manage, User, :self_managed => true
query(:manage, User).conditions # => "not (self_managed = 't') AND ((manager_id = 1) OR (id = 1))"
63 64 65 66 67 68 69 70 71 |
# File 'lib/cancan/model_adapters/active_record_adapter.rb', line 63 def conditions conditions_extractor = ConditionsExtractor.new(@model_class) if @compressed_rules.size == 1 && @compressed_rules.first.base_behavior # Return the conditions directly if there's just one definition conditions_extractor.tableize_conditions(@compressed_rules.first.conditions).dup else extract_multiple_conditions(conditions_extractor, @compressed_rules) end end |
#database_records ⇒ Object
79 80 81 82 83 84 85 86 87 |
# File 'lib/cancan/model_adapters/active_record_adapter.rb', line 79 def database_records if override_scope @model_class.where(nil).merge(override_scope) elsif @model_class.respond_to?(:where) && @model_class.respond_to?(:joins) build_relation(conditions) else @model_class.all(conditions: conditions, joins: joins) end end |
#extract_multiple_conditions(conditions_extractor, rules) ⇒ Object
73 74 75 76 77 |
# File 'lib/cancan/model_adapters/active_record_adapter.rb', line 73 def extract_multiple_conditions(conditions_extractor, rules) rules.reverse.inject(false_sql) do |sql, rule| merge_conditions(sql, conditions_extractor.tableize_conditions(rule.conditions).dup, rule.base_behavior) end end |
#joins ⇒ Object
Returns the associations used in conditions for the :joins option of a search. See ModelAdditions#accessible_by
99 100 101 102 103 104 105 |
# File 'lib/cancan/model_adapters/active_record_adapter.rb', line 99 def joins joins_hash = {} @compressed_rules.reverse_each do |rule| deep_merge(joins_hash, rule.associations_hash) end deep_clean(joins_hash) unless joins_hash.empty? end |