diff --git a/lib/vault/encrypted_model.rb b/lib/vault/encrypted_model.rb index aea98b9f..fffaf8df 100644 --- a/lib/vault/encrypted_model.rb +++ b/lib/vault/encrypted_model.rb @@ -200,6 +200,13 @@ def __vault_load_attributes! end end + # In rails 4.2, virtual attributes are not excluded from joins aliases + if ActiveRecord.version < Gem::Version.new('5.0.0') + def self.column_names + super - __vault_attributes.keys.map(&:to_s) + end + end + # Decrypt and load a single attribute from Vault. def __vault_load_attribute!(attribute, options) # If the user provided a value for the attribute, do not try to load it from Vault diff --git a/spec/dummy/app/models/person.rb b/spec/dummy/app/models/person.rb index 1324df9b..04892a15 100644 --- a/spec/dummy/app/models/person.rb +++ b/spec/dummy/app/models/person.rb @@ -3,6 +3,8 @@ class Person < ActiveRecord::Base include Vault::EncryptedModel + has_many :problems + vault_attribute :county_plaintext, encrypted_column: :county_encrypted vault_attribute_proxy :county, :county_plaintext diff --git a/spec/dummy/app/models/problem.rb b/spec/dummy/app/models/problem.rb new file mode 100644 index 00000000..70a4fa6a --- /dev/null +++ b/spec/dummy/app/models/problem.rb @@ -0,0 +1,3 @@ +class Problem < ActiveRecord::Base + belongs_to :person +end diff --git a/spec/dummy/db/migrate/20181024200800_create_problems.rb b/spec/dummy/db/migrate/20181024200800_create_problems.rb new file mode 100644 index 00000000..8bc6884b --- /dev/null +++ b/spec/dummy/db/migrate/20181024200800_create_problems.rb @@ -0,0 +1,10 @@ +class CreateProblems < ActiveRecord::Migration[5.0] + def change + create_table :problems do |t| + t.references :person + t.string :title + + t.timestamps + end + end +end diff --git a/spec/dummy/db/schema.rb b/spec/dummy/db/schema.rb index 3b6e3c89..8f086198 100644 --- a/spec/dummy/db/schema.rb +++ b/spec/dummy/db/schema.rb @@ -10,30 +10,34 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_10_17_154000) do +ActiveRecord::Schema.define(version: 20181024200800) do create_table "people", force: :cascade do |t| - t.string "name" - t.string "ssn_encrypted" - t.string "cc_encrypted" - t.string "details_encrypted" - t.string "business_card_encrypted" - t.string "favorite_color_encrypted" - t.string "non_ascii_encrypted" + t.string "name" + t.string "ssn_encrypted" + t.string "cc_encrypted" + t.string "details_encrypted" + t.string "business_card_encrypted" + t.string "favorite_color_encrypted" + t.string "non_ascii_encrypted" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "email_encrypted" + t.string "integer_data_encrypted" + t.string "float_data_encrypted" + t.string "time_data_encrypted" + t.string "county" + t.string "county_encrypted" + t.string "state" + t.string "state_encrypted" + end + + create_table "problems", force: :cascade do |t| + t.integer "person_id" + t.string "title" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.string "email_encrypted" - t.string "address" - t.string "address_encrypted" - t.date "date_of_birth" - t.string "date_of_birth_encrypted" - t.string "integer_data_encrypted" - t.string "float_data_encrypted" - t.string "time_data_encrypted" - t.string "county" - t.string "county_encrypted" - t.string "state" - t.string "state_encrypted" + t.index ["person_id"], name: "index_problems_on_person_id" end end diff --git a/spec/unit/encrypted_model_spec.rb b/spec/unit/encrypted_model_spec.rb index 86412957..3051d63c 100644 --- a/spec/unit/encrypted_model_spec.rb +++ b/spec/unit/encrypted_model_spec.rb @@ -1,8 +1,44 @@ require "spec_helper" describe Vault::EncryptedModel do + describe 'query methods' do + let!(:person) { Person.create } + let!(:small_problem) { Problem.create person: person, title: 'small problem' } + let!(:big_problem) { Problem.create person: person, title: 'big problem' } + + it 'works with includes' do + expect do + Person.where(id: person.id).includes(:problems).first + end.not_to raise_error + end + + it 'works with where and references' do + expect do + Person.includes(:problems).where('problems.title like ?', '%small%').references(:problems).first + end.not_to raise_error + end + + it 'works with where and association hash' do + expect do + Problem.where(person: person).first + end.not_to raise_error + end + + it 'works with joins' do + expect do + Person.where(id: person.id).joins(:problems).first + end.not_to raise_error + end + + it 'works with joins and includes' do + expect do + Person.joins(:problems).includes(:problems).first + end.not_to raise_error + end + end + describe ".vault_attribute" do - let(:person) { Person.new } + let(:person) { Person.create } it "raises an exception if a serializer and :encode is given" do expect {