Browse Source

domain#name_reversed cache for indexing and searching and domain ownership validation accounting for permissions

pull/1/head
Nicolae Claudius 13 years ago
parent
commit
ea5eff64a2
  1. 6
      app/models/domain.rb
  2. 6
      app/models/user.rb
  3. 15
      db/migrate/20120112175527_add_name_reversed_to_domains.rb
  4. 20
      spec/models/domain_spec.rb
  5. 3
      spec/support/shared_context/data.rb

6
app/models/domain.rb

@ -50,7 +50,7 @@ class Domain < ActiveRecord::Base
errors[:name] = "cannot be a TLD or a reserved domain" if Tld.include?(name)
# if parent domain is on our system, the user must own it
if parent_domain.present? && parent_domain.user_id != user_id
if parent_domain.present? && user.cannot?(:manage, parent_domain)
errors[:name] = "issue, the parent domain `#{parent_domain.name}` is registered to another user"
end
end
@ -74,6 +74,10 @@ class Domain < ActiveRecord::Base
a_records.build(:content => ip) if ip.present?
end
before_save do
self.name_reversed = name.reverse if name_changed?
end
before_validation(:on => :update) do
if name_changed?
name_was_pattern = /#{Regexp.escape(name_was)}$/

6
app/models/user.rb

@ -24,4 +24,10 @@ class User < ActiveRecord::Base
"#{first_name} #{last_name}"
end
delegate :can?, :cannot?, :to => :ability
def ability
@ability ||= Ability.new(self)
end
end

15
db/migrate/20120112175527_add_name_reversed_to_domains.rb

@ -0,0 +1,15 @@
class AddNameReversedToDomains < ActiveRecord::Migration
def up
# used for "%" search indexing in an ancestry fashion (materialized path pattern)
# http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html
add_column :domains, :name_reversed, :string, :limit => 255
execute "UPDATE domains SET name_reversed = REVERSE(name)"
change_column :domains, :name_reversed, :string, :limit => 255, :null => false
add_index :domains, :name_reversed
end
def down
remove_index :domains, :column => :name_reversed
remove_column :domains, :name_reversed
end
end

20
spec/models/domain_spec.rb

@ -46,6 +46,11 @@ describe Domain do
domain.should be_valid
end
it "has parent_domain" do
subdomain = build(:domain, :user => other_user, :name => "x.#{domain.name}")
subdomain.parent_domain.should == domain
end
it "validates ownership" do
domain.name = 'co.uk'
domain.should have(1).errors_on(:name)
@ -53,9 +58,13 @@ describe Domain do
domain.name = 'clyfe.ro'
domain.should be_valid
# stub a parent domain on another user account
mock_domain = mock(:user_id => domain.user_id + 1, :name => 'x')
Domain.stub_chain('find_by_name').and_return(mock_domain)
# stub a parent domain on another user account, with no permissions present
mock_domain = mock(
:user_id => third_user.id,
:user => third_user,
:name => 'x'
)
Domain.stub(:find_by_name).and_return(mock_domain)
domain.should have(1).errors_on(:name)
end
@ -66,4 +75,9 @@ describe Domain do
joins.should == [[:permissions, Arel::Nodes::OuterJoin]]
end
it "has reversed name" do
domain.name_reversed.should be_present
domain.name_reversed.should == domain.name.reverse
end
end

3
spec/support/shared_context/data.rb

@ -6,6 +6,9 @@ shared_context "data" do
let(:other_user){create(:user)}
let(:other_user_ability){Ability.new(:user => other_user)}
let(:third_user){create(:user)}
let(:third_user_ability){Ability.new(:user => third_user)}
let(:domain){
domain = build(:domain, :user => user)
domain.setup(FactoryGirl.generate(:email))

Loading…
Cancel
Save