handle deeply nested conditions properly in active record adapter - closes #246

This commit is contained in:
Ryan Bates 2011-01-20 10:12:46 -08:00
parent 5c4c179c5a
commit f9ad4858f5
2 changed files with 22 additions and 3 deletions

View File

@ -31,12 +31,13 @@ module CanCan
end end
end end
def tableized_conditions(conditions) def tableized_conditions(conditions, model_class = @model_class)
return conditions unless conditions.kind_of? Hash return conditions unless conditions.kind_of? Hash
conditions.inject({}) do |result_hash, (name, value)| conditions.inject({}) do |result_hash, (name, value)|
if value.kind_of? Hash if value.kind_of? Hash
name = @model_class.reflect_on_association(name).table_name association_class = model_class.reflect_on_association(name).class_name.constantize
value = tableized_conditions(value) name = model_class.reflect_on_association(name).table_name
value = tableized_conditions(value, association_class)
end end
result_hash[name] = value result_hash[name] = value
result_hash result_hash

View File

@ -8,12 +8,23 @@ if ENV["MODEL_ADAPTER"].nil? || ENV["MODEL_ADAPTER"] == "active_record"
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:") ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
describe CanCan::ModelAdapters::ActiveRecordAdapter do describe CanCan::ModelAdapters::ActiveRecordAdapter do
with_model :category do
table do |t|
t.boolean "visible"
end
model do
has_many :articles
end
end
with_model :article do with_model :article do
table do |t| table do |t|
t.boolean "published" t.boolean "published"
t.boolean "secret" t.boolean "secret"
t.integer "category_id"
end end
model do model do
belongs_to :category
has_many :comments has_many :comments
end end
end end
@ -88,6 +99,13 @@ if ENV["MODEL_ADAPTER"].nil? || ENV["MODEL_ADAPTER"] == "active_record"
Comment.accessible_by(@ability).should == [comment1] Comment.accessible_by(@ability).should == [comment1]
end end
it "should only read comments for visible categories through articles" do
@ability.can :read, Comment, :article => { :category => { :visible => true } }
comment1 = Comment.create!(:article => Article.create!(:category => Category.create!(:visible => true)))
comment2 = Comment.create!(:article => Article.create!(:category => Category.create!(:visible => false)))
Comment.accessible_by(@ability).should == [comment1]
end
it "should allow conditions in SQL and merge with hash conditions" do it "should allow conditions in SQL and merge with hash conditions" do
@ability.can :read, Article, :published => true @ability.can :read, Article, :published => true
@ability.can :read, Article, ["secret=?", true] @ability.can :read, Article, ["secret=?", true]