acts_as_customized_attributes 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +5 -13
  2. data/README.md +3 -3
  3. data/Rakefile +15 -11
  4. data/config/routes.rb +1 -0
  5. data/lib/acts_as_customized_attributes.rb +1 -0
  6. data/lib/acts_as_customized_attributes/class_methods.rb +95 -13
  7. data/lib/acts_as_customized_attributes/compatibility.rb +1 -0
  8. data/lib/acts_as_customized_attributes/engine.rb +4 -2
  9. data/lib/acts_as_customized_attributes/instance_methods.rb +7 -6
  10. data/lib/acts_as_customized_attributes/version.rb +2 -1
  11. data/lib/tasks/acts_as_customized_attributes_tasks.rake +1 -0
  12. data/spec/dummy/Rakefile +2 -1
  13. data/spec/dummy/app/controllers/application_controller.rb +1 -0
  14. data/spec/dummy/app/helpers/application_helper.rb +1 -0
  15. data/spec/dummy/app/models/order.rb +1 -0
  16. data/spec/dummy/app/models/user.rb +1 -0
  17. data/spec/dummy/config.ru +2 -1
  18. data/spec/dummy/config/application.rb +4 -4
  19. data/spec/dummy/config/boot.rb +6 -5
  20. data/spec/dummy/config/database.example.yml +6 -37
  21. data/spec/dummy/config/database.shippable.yml +2 -5
  22. data/spec/dummy/config/database.yml +9 -16
  23. data/spec/dummy/config/environment.rb +2 -1
  24. data/spec/dummy/config/environments/development.rb +2 -0
  25. data/spec/dummy/config/environments/production.rb +3 -1
  26. data/spec/dummy/config/environments/test.rb +4 -2
  27. data/spec/dummy/config/initializers/backtrace_silencers.rb +1 -0
  28. data/spec/dummy/config/initializers/inflections.rb +1 -0
  29. data/spec/dummy/config/initializers/mime_types.rb +1 -0
  30. data/spec/dummy/config/initializers/secret_token.rb +3 -1
  31. data/spec/dummy/config/initializers/session_store.rb +2 -1
  32. data/spec/dummy/config/initializers/wrap_parameters.rb +1 -0
  33. data/spec/dummy/config/routes.rb +1 -0
  34. data/spec/dummy/db/development.sqlite3 +0 -0
  35. data/spec/dummy/db/migrate/20141118114902_create_users.rb +1 -0
  36. data/spec/dummy/db/migrate/20141118114941_create_user_customized_attributes.rb +1 -0
  37. data/spec/dummy/db/migrate/20141118134833_create_orders.rb +1 -0
  38. data/spec/dummy/db/migrate/20141118135027_create_order_customized_attributes.rb +1 -0
  39. data/spec/dummy/db/schema.rb +16 -16
  40. data/spec/dummy/db/test.sqlite3 +0 -0
  41. data/spec/dummy/log/development.log +153 -0
  42. data/spec/dummy/log/test.log +2278 -0
  43. data/spec/dummy/script/rails +4 -3
  44. data/spec/factories/order.rb +1 -0
  45. data/spec/factories/user.rb +1 -0
  46. data/spec/models/user_spec.rb +23 -22
  47. data/spec/spec_helper.rb +8 -7
  48. metadata +64 -34
  49. data/app/models/acts_as_customized_attributes/data.rb +0 -29
  50. data/app/models/acts_as_customized_attributes/data_key.rb +0 -52
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- OWIxNDQ5MjA4ZjBmYzAxZDU0NDJiYTRhYzExZjMwZGE2Y2E4NDZhYg==
5
- data.tar.gz: !binary |-
6
- MjM5NGRkYzIzZTBlYTUzYWU2MDljNGI0ZTAwZWE5ODAxMjM4M2Y2Zg==
2
+ SHA1:
3
+ metadata.gz: 6cf3da61d6819da1a7d8562dcad8619affda62f5
4
+ data.tar.gz: 36bc64c145508ac95af5dfe0045854979bc13412
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- ODQ4MGQyNGMyMjkxYzdiOGEzNWVhYTVhYmU2MTYxNTQyM2UwZmY3ZGNiNDM0
10
- MjRjMWVhMWI5MDllNTEwYWVhMzNkZDhkODYzNjFkODc2MGRmZGRmN2FmNzA3
11
- MTI2NzgwYzc4NDgxOGI4ZTU3NjEzYWExN2ZmZDNiNTA3ODU0NzI=
12
- data.tar.gz: !binary |-
13
- ODM1NWFkM2FjZDY1ODUxMGZiZDhiZjYyMWExYTAzODUxYWY1ZGIyZThlZTQx
14
- YzdhYWRmYTI4ZmVlMjE5NTFkNGQ3ZmU1ZGMxOGIzNjgxMDgyYzc2NTcxODA0
15
- YzcwMGUxYmZmZDUzZmYzZmEwZTFlNjFiNzE0NGNhODkyYzg4Yjk=
6
+ metadata.gz: b0947725f00d7d5f619a78f7a291f0a7250752a8730f2f29ffb6d6dc5da16e8eb65109a31b87a81962ca44ceeb140a8ed13d50f4123c2b8c619f90af3e78b037
7
+ data.tar.gz: 82dfbf339ae77a97b164b94ed38c61ee5e4fa2fd0689af80108a5c743cab765f24c72186b0948f36f26e93f092352438d3ed06f4867e623a75c2823c57494440
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- [![Build Status](https://api.shippable.com/projects/546b3f7bd46935d5fbbde6b9/badge?branchName=master)](https://app.shippable.com/projects/546b3f7bd46935d5fbbde6b9/builds/latest)
2
1
  [![Code Climate](https://codeclimate.com/github/kaspernj/acts_as_customized_attributes/badges/gpa.svg)](https://codeclimate.com/github/kaspernj/acts_as_customized_attributes)
3
2
  [![Test Coverage](https://codeclimate.com/github/kaspernj/acts_as_customized_attributes/badges/coverage.svg)](https://codeclimate.com/github/kaspernj/acts_as_customized_attributes)
3
+ [![Build Status](https://img.shields.io/shippable/546b3f7bd46935d5fbbde6b9.svg)](https://app.shippable.com/projects/546b3f7bd46935d5fbbde6b9/builds/latest)
4
4
 
5
5
  # ActsAsCustomizedAttributes
6
6
 
@@ -59,13 +59,13 @@ some_model.customized_attributes #=> {:my_custom_attribute => 5}
59
59
  #### Query keys.
60
60
 
61
61
  ```ruby
62
- SomeModel::DataKey.where("name LIKE '%facebook%'")
62
+ SomeModelDataKey.where("name LIKE '%facebook%'")
63
63
  ```
64
64
 
65
65
  ### Query data
66
66
 
67
67
  ```ruby
68
- SomeModel::Data.where("resource_id > 5")
68
+ SomeModelData.where("resource_id > 5")
69
69
  ```
70
70
 
71
71
  ### Optimize inserts with transactions for inserts / updates.
data/Rakefile CHANGED
@@ -1,26 +1,30 @@
1
1
  #!/usr/bin/env rake
2
+ # frozen_string_literal: true
2
3
  begin
3
- require 'bundler/setup'
4
+ require "bundler/setup"
4
5
  rescue LoadError
5
- puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ puts "You must `gem install bundler` and `bundle install` to run rake tasks"
6
7
  end
7
8
  begin
8
- require 'rdoc/task'
9
+ require "rdoc/task"
9
10
  rescue LoadError
10
- require 'rdoc/rdoc'
11
- require 'rake/rdoctask'
11
+ require "rdoc/rdoc"
12
+ require "rake/rdoctask"
12
13
  RDoc::Task = Rake::RDocTask
13
14
  end
14
15
 
15
16
  RDoc::Task.new(:rdoc) do |rdoc|
16
- rdoc.rdoc_dir = 'rdoc'
17
- rdoc.title = 'ActsAsCustomizedAttributes'
18
- rdoc.options << '--line-numbers'
19
- rdoc.rdoc_files.include('README.md')
20
- rdoc.rdoc_files.include('lib/**/*.rb')
17
+ rdoc.rdoc_dir = "rdoc"
18
+ rdoc.title = "ActsAsCustomizedAttributes"
19
+ rdoc.options << "--line-numbers"
20
+ rdoc.rdoc_files.include("README.md")
21
+ rdoc.rdoc_files.include("lib/**/*.rb")
21
22
  end
22
23
 
23
24
  APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
24
- load 'rails/tasks/engine.rake'
25
+ load "rails/tasks/engine.rake"
26
+
27
+ require "best_practice_project"
28
+ BestPracticeProject.load_tasks
25
29
 
26
30
  Bundler::GemHelper.install_tasks
data/config/routes.rb CHANGED
@@ -1,2 +1,3 @@
1
+ # frozen_string_literal: true
1
2
  Rails.application.routes.draw do
2
3
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "acts_as_customized_attributes/engine"
2
3
 
3
4
  module ActsAsCustomizedAttributes
@@ -1,20 +1,102 @@
1
+ # frozen_string_literal: true
1
2
  module ActsAsCustomizedAttributes::ClassMethods
2
- def acts_as_customized_attributes(args = {})
3
+ def acts_as_customized_attributes(_args = {})
3
4
  $aaca_class_name_key = "#{name}DataKey"
4
5
  $aaca_class_name_data = "#{name}Data"
5
6
  $original_class_name = name
6
7
 
7
- class_data_key = Class.new(ActsAsCustomizedAttributes::DataKey) do
8
- set_table_name $aaca_class_name_key.tableize
8
+ class_data_key = Class.new(ActiveRecord::Base) do
9
+ if respond_to?(:set_table_name)
10
+ set_table_name $aaca_class_name_key.tableize
11
+ else
12
+ self.table_name = $aaca_class_name_key.tableize
13
+ end
14
+
15
+ after_create :add_to_cache
16
+ after_update :add_to_cache
17
+ after_destroy :remove_from_cache
18
+ before_update :remove_from_cache
19
+
20
+ validates_presence_of :name
21
+ validate :validate_unique_name
9
22
 
10
- has_many :data, class_name: $aaca_class_name_data, foreign_key: "data_key_id", dependent: :destroy
23
+ has_many :data, class_name: $aaca_class_name_data.to_s, table_name: $aaca_class_name_data.tableize.to_s, foreign_key: "data_key_id", dependent: :destroy
24
+
25
+ def self.id_for_name(name)
26
+ cache_name_to_id.fetch(name.to_s)
27
+ end
28
+
29
+ def self.name_for_id(id)
30
+ cache_name_to_id.key(id) || raise(KeyError, "No such ID: #{id}")
31
+ end
32
+
33
+ def self.cache_name_to_id
34
+ update_cache_name_to_id unless @cache_name_to_id
35
+ @cache_name_to_id
36
+ end
37
+
38
+ # Initializes / reloads the cache.
39
+ def self.update_cache_name_to_id
40
+ @cache_name_to_id = {}
41
+ find_each do |data_key|
42
+ @cache_name_to_id[data_key.name] = data_key.id
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def add_to_cache
49
+ self.class.cache_name_to_id[name.to_s] = id
50
+ end
51
+
52
+ def remove_from_cache
53
+ self.class.cache_name_to_id.delete(name_was)
54
+ end
55
+
56
+ def validate_unique_name
57
+ id_exists = self.class.id_for_name(name)
58
+
59
+ errors.add :name, :taken if id_exists != id
60
+ rescue KeyError
61
+ # No problem.
62
+ end
11
63
  end
12
64
 
13
- class_data = Class.new(ActsAsCustomizedAttributes::Data) do
14
- set_table_name $aaca_class_name_data.tableize
65
+ class_data = Class.new(ActiveRecord::Base) do
66
+ if respond_to?(:set_table_name)
67
+ set_table_name $aaca_class_name_data.tableize
68
+ else
69
+ self.table_name = $aaca_class_name_data.tableize
70
+ end
71
+
72
+ belongs_to :resource, class_name: $original_class_name.to_s
73
+ belongs_to :data_key, class_name: $aaca_class_name_key.to_s
74
+
75
+ validate :associated_resource_and_data_key
76
+
77
+ def self.key_class=(key_class)
78
+ @key_class = key_class
79
+ end
80
+
81
+ def self.key_class
82
+ @key_class
83
+ end
84
+
85
+ private
86
+
87
+ def associated_resource_and_data_key
88
+ return errors.add :data_key_id, "not valid" unless data_key_id?
15
89
 
16
- belongs_to :resource, class_name: $original_class_name
17
- belongs_to :data_key, class_name: $aaca_class_name_key
90
+ if !resource_id? || !resource
91
+ return errors.add :resource_id, "not associated"
92
+ end
93
+
94
+ begin
95
+ self.class.key_class.name_for_id(data_key_id)
96
+ rescue KeyError
97
+ errors.add :data_key_id, "doesn't exist"
98
+ end
99
+ end
18
100
  end
19
101
 
20
102
  Object.const_set($aaca_class_name_key, class_data_key)
@@ -59,8 +141,9 @@ private
59
141
  def migration_class
60
142
  $acts_as_customized_attributes_keys_table_name = "#{name.downcase}_data_keys"
61
143
  $acts_as_customized_attributes_table_name = "#{name.downcase}_data"
144
+ $table_name = table_name
62
145
 
63
- clazz = Class.new(ActiveRecord::Migration) do
146
+ Class.new(ActiveRecord::Migration) do
64
147
  def up
65
148
  create_table $acts_as_customized_attributes_keys_table_name do |t|
66
149
  t.string :name
@@ -71,14 +154,13 @@ private
71
154
  add_index $acts_as_customized_attributes_keys_table_name, :name, unique: true
72
155
 
73
156
  create_table $acts_as_customized_attributes_table_name do |t|
74
- t.belongs_to :resource
75
- t.belongs_to :data_key
157
+ t.belongs_to :resource, index: true
158
+ t.belongs_to :data_key, index: true
76
159
  t.string :value
77
160
  t.timestamps
78
161
  end
79
162
 
80
- add_index $acts_as_customized_attributes_table_name, :data_key_id
81
- add_index $acts_as_customized_attributes_table_name, :resource_id
163
+ add_foreign_key $acts_as_customized_attributes_table_name, $table_name, column: "data_key_id", on_delete: :cascade
82
164
  add_index $acts_as_customized_attributes_table_name, [:data_key_id, :resource_id], unique: true
83
165
  end
84
166
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ActsAsCustomizedAttributes::Compatibility
2
3
  def self.included(base)
3
4
  base.extend ActsAsCustomizedAttributes::ClassMethods
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  module ActsAsCustomizedAttributes
2
- class Engine < Rails::Engine
3
- end
3
+ end
4
+
5
+ class ActsAsCustomizedAttributes::Engine < Rails::Engine
4
6
  end
@@ -1,13 +1,14 @@
1
+ # frozen_string_literal: true
1
2
  module ActsAsCustomizedAttributes::InstanceMethods
2
3
  def update_customized_attributes(data)
3
4
  update_customized_attributes_with_args(data: data)
4
5
  end
5
6
 
6
- UPDATE_CUSTOMIZED_ATTRIBUTES_VALID_ARGS = [:data, :transactioner]
7
+ UPDATE_CUSTOMIZED_ATTRIBUTES_VALID_ARGS = [:data, :transactioner].freeze
7
8
  def update_customized_attributes_with_args(args)
8
- args.each { |key, value| raise "Invalid argument: '#{key}'." unless UPDATE_CUSTOMIZED_ATTRIBUTES_VALID_ARGS.include?(key) }
9
+ args.each { |key, _value| raise "Invalid argument: '#{key}'." unless UPDATE_CUSTOMIZED_ATTRIBUTES_VALID_ARGS.include?(key) }
9
10
 
10
- args[:data].each do |key, value|
11
+ args.fetch(:data).each do |key, value|
11
12
  begin
12
13
  key_id = self.class.aaca_key_class.id_for_name(key)
13
14
  rescue KeyError
@@ -15,12 +16,12 @@ module ActsAsCustomizedAttributes::InstanceMethods
15
16
  key_id = key_model.id
16
17
  end
17
18
 
18
- data_model = self.data.where(data_key_id: key_id).first
19
+ data_model = data.where(data_key_id: key_id).first
19
20
  if data_model
20
21
  data_model.resource = self # Saves query when validating.
21
22
  else
22
23
  # Set resource in order to skip query when validating.
23
- data_model = self.data.new(data_key_id: key_id, resource: self)
24
+ data_model = data.new(data_key_id: key_id, resource: self)
24
25
  end
25
26
 
26
27
  data_model.value = value
@@ -45,6 +46,6 @@ module ActsAsCustomizedAttributes::InstanceMethods
45
46
  hash[key_name.to_sym] = data_i.value
46
47
  end
47
48
 
48
- return hash
49
+ hash
49
50
  end
50
51
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ActsAsCustomizedAttributes
2
- VERSION = "0.0.6"
3
+ VERSION = "0.0.7"
3
4
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # desc "Explaining what the task does"
2
3
  # task :acts_as_customized_attributes do
3
4
  # # Task goes here
data/spec/dummy/Rakefile CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env rake
2
+ # frozen_string_literal: true
2
3
  # Add your own tasks in files placed in lib/tasks ending in .rake,
3
4
  # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
4
5
 
5
- require File.expand_path('../config/application', __FILE__)
6
+ require File.expand_path("../config/application", __FILE__)
6
7
 
7
8
  Dummy::Application.load_tasks
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class ApplicationController < ActionController::Base
2
3
  protect_from_forgery
3
4
  end
@@ -1,2 +1,3 @@
1
+ # frozen_string_literal: true
1
2
  module ApplicationHelper
2
3
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Order < ActiveRecord::Base
2
3
  acts_as_customized_attributes
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class User < ActiveRecord::Base
2
3
  acts_as_customized_attributes
3
4
  end
data/spec/dummy/config.ru CHANGED
@@ -1,4 +1,5 @@
1
+ # frozen_string_literal: true
1
2
  # This file is used by Rack-based servers to start the application.
2
3
 
3
- require ::File.expand_path('../config/environment', __FILE__)
4
+ require ::File.expand_path("../config/environment", __FILE__)
4
5
  run Dummy::Application
@@ -1,6 +1,7 @@
1
- require File.expand_path('../boot', __FILE__)
1
+ # frozen_string_literal: true
2
+ require File.expand_path("../boot", __FILE__)
2
3
 
3
- require 'rails/all'
4
+ require "rails/all"
4
5
 
5
6
  Bundler.require
6
7
  require "acts_as_customized_attributes"
@@ -39,7 +40,6 @@ module Dummy
39
40
  config.assets.enabled = true
40
41
 
41
42
  # Version of your assets, change this if you want to expire all your assets
42
- config.assets.version = '1.0'
43
+ config.assets.version = "1.0"
43
44
  end
44
45
  end
45
-
@@ -1,10 +1,11 @@
1
- require 'rubygems'
2
- gemfile = File.expand_path('../../../../Gemfile', __FILE__)
1
+ # frozen_string_literal: true
2
+ require "rubygems"
3
+ gemfile = File.expand_path("../../../../Gemfile", __FILE__)
3
4
 
4
5
  if File.exist?(gemfile)
5
- ENV['BUNDLE_GEMFILE'] = gemfile
6
- require 'bundler'
6
+ ENV["BUNDLE_GEMFILE"] = gemfile
7
+ require "bundler"
7
8
  Bundler.setup
8
9
  end
9
10
 
10
- $:.unshift File.expand_path('../../../../lib', __FILE__)
11
+ $LOAD_PATH.unshift File.expand_path("../../../../lib", __FILE__)
@@ -1,42 +1,11 @@
1
- # MySQL. Versions 4.1 and 5.0 are recommended.
2
- #
3
- # Install the MYSQL driver
4
- # gem install mysql2
5
- #
6
- # Ensure the MySQL gem is defined in your Gemfile
7
- # gem 'mysql2'
8
- #
9
- # And be sure to use new-style password hashing:
10
- # http://dev.mysql.com/doc/refman/5.0/en/old-client.html
11
1
  development:
12
- adapter: mysql2
13
- encoding: utf8
14
- reconnect: false
15
- database: dummy_development
16
- pool: 5
17
- username: root
18
- password:
19
- socket: /var/run/mysqld/mysqld.sock
2
+ adapter: sqlite3
3
+ database: db/development.sqlite3
20
4
 
21
- # Warning: The database defined as "test" will be erased and
22
- # re-generated from your development database when you run "rake".
23
- # Do not set this db to the same as development or production.
24
5
  test:
25
- adapter: mysql2
26
- encoding: utf8
27
- reconnect: false
28
- database: dummy_test
29
- pool: 5
30
- username: root
31
- password:
32
- socket: /var/run/mysqld/mysqld.sock
6
+ adapter: sqlite3
7
+ database: db/test.sqlite3
33
8
 
34
9
  production:
35
- adapter: mysql2
36
- encoding: utf8
37
- reconnect: false
38
- database: dummy_production
39
- pool: 5
40
- username: root
41
- password:
42
- socket: /var/run/mysqld/mysqld.sock
10
+ adapter: sqlite3
11
+ database: db/production.sqlite3
@@ -1,6 +1,3 @@
1
1
  test:
2
- adapter: mysql2
3
- encoding: utf8
4
- database: acts_as_customized_attributes
5
- pool: 5
6
- username: shippa
2
+ adapter: sqlite3
3
+ database: db/test.sqlite3