has_preference 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README +15 -0
- data/Rakefile +68 -0
- data/app/models/preference.rb +41 -0
- data/init.rb +4 -0
- data/lib/generators/has_attribute/migration_generator.rb +11 -0
- data/lib/generators/has_attribute/template/migration.rb +13 -0
- data/lib/generators/has_preference.rb +18 -0
- data/lib/generators/has_preference/migration/migration_generator.rb +13 -0
- data/lib/generators/has_preference/migration/templates/migration.rb +13 -0
- data/lib/has_preference.rb +361 -0
- metadata +77 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Thomas Boerger <tboerger@tbpro.de>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# has_preference
|
2
|
+
|
3
|
+
Add preference functionality to your ActiveRecord models.
|
4
|
+
|
5
|
+
## Install
|
6
|
+
|
7
|
+
gem 'has_preference'
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
## Credits
|
14
|
+
|
15
|
+
The project <tt>has_preference</tt> have been inspired by pluginaweek. Take a look at the git [repositories](https://github.com/pluginaweek).
|
data/Rakefile
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# Created by Thomas Boerger on 2011-07-01.
|
2
|
+
# Copyright (c) 2011. All rights reserved.
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'rubygems/package_task'
|
6
|
+
require 'rubygems/specification'
|
7
|
+
require 'rake'
|
8
|
+
require 'rake/testtask'
|
9
|
+
require 'rdoc/task'
|
10
|
+
require 'rcov/rcovtask'
|
11
|
+
require 'date'
|
12
|
+
|
13
|
+
GEM_TITLE = 'has_preference'
|
14
|
+
GEM_VERSION = '0.0.1'
|
15
|
+
|
16
|
+
spec = Gem::Specification.new do |s|
|
17
|
+
s.name = GEM_TITLE
|
18
|
+
s.version = GEM_VERSION
|
19
|
+
s.platform = Gem::Platform::RUBY
|
20
|
+
s.extra_rdoc_files = ['README', 'LICENSE']
|
21
|
+
s.rdoc_options << '--line-numbers' << '--main=README'
|
22
|
+
s.summary = 'Has preference'
|
23
|
+
s.description = 'Preference for ActiveRecord models'
|
24
|
+
s.author = 'Thomas Boerger'
|
25
|
+
s.email = 'tboerger@tbpro.de'
|
26
|
+
s.homepage = 'http://github.com/tbpro/has_preference'
|
27
|
+
s.files = %w(LICENSE README Rakefile init.rb) + Dir.glob('{app,generators,lib,test}/**/*')
|
28
|
+
s.test_files = Dir["test/**/*_test.rb"]
|
29
|
+
end
|
30
|
+
|
31
|
+
Gem::PackageTask.new(spec) do |pkg|
|
32
|
+
pkg.gem_spec = spec
|
33
|
+
end
|
34
|
+
|
35
|
+
desc 'Create a gemspec'
|
36
|
+
task :writespec do
|
37
|
+
File.open("#{GEM_TITLE}.gemspec", "w") do |file|
|
38
|
+
file.puts spec.to_ruby
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
desc 'Docs for gem'
|
43
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
44
|
+
rdoc.rdoc_dir = 'doc'
|
45
|
+
rdoc.title = spec.name
|
46
|
+
rdoc.options << '--line-numbers' << '--main=README'
|
47
|
+
rdoc.rdoc_files.include('README', 'LICENSE', 'lib/**/*.rb', 'app/**/*.rb')
|
48
|
+
end
|
49
|
+
|
50
|
+
#desc 'Tests for gem'
|
51
|
+
#Rake::TestTask.new(:test) do |t|
|
52
|
+
# t.libs << 'lib'
|
53
|
+
# t.test_files = spec.test_files
|
54
|
+
# t.verbose = true
|
55
|
+
#end
|
56
|
+
|
57
|
+
#desc 'Rcov for gem'
|
58
|
+
#Rcov::RcovTask.new(:rcov) do |t|
|
59
|
+
# t.libs << 'lib'
|
60
|
+
# t.test_files = spec.test_files
|
61
|
+
# t.rcov_opts << '--exclude="^(?!lib/|app/)"'
|
62
|
+
# t.verbose = true
|
63
|
+
#end
|
64
|
+
|
65
|
+
desc 'List all tasks'
|
66
|
+
task :default do
|
67
|
+
puts `rake -T`.grep(/^[^(].*$/)
|
68
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class Preference < ActiveRecord::Base
|
2
|
+
belongs_to :owner, :polymorphic => true
|
3
|
+
belongs_to :group, :polymorphic => true
|
4
|
+
|
5
|
+
validates_presence_of :name, :owner_id, :owner_type
|
6
|
+
validates_presence_of :group_type, :if => :group_id?
|
7
|
+
|
8
|
+
def definition
|
9
|
+
owner_type && (find_definition(owner_type.constantize) || find_definition(owner.class))
|
10
|
+
end
|
11
|
+
|
12
|
+
def value
|
13
|
+
value = read_attribute(:value)
|
14
|
+
value = definition.type_cast(value) if definition
|
15
|
+
|
16
|
+
value
|
17
|
+
end
|
18
|
+
|
19
|
+
def group_with_optional_lookup
|
20
|
+
group_id ? group_without_optional_lookup : group_type
|
21
|
+
end
|
22
|
+
|
23
|
+
alias_method_chain :group, :optional_lookup
|
24
|
+
|
25
|
+
class << self
|
26
|
+
def split_group(group = nil)
|
27
|
+
if group.is_a?(ActiveRecord::Base)
|
28
|
+
group_id, group_type = group.id, group.class.base_class.name.to_s
|
29
|
+
else
|
30
|
+
group_id, group_type = nil, group.is_a?(Symbol) ? group.to_s : group
|
31
|
+
end
|
32
|
+
|
33
|
+
[group_id, group_type]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
def find_definition(owner_class)
|
39
|
+
owner_class.respond_to?(:preference_definitions) && owner_class.preference_definitions[name]
|
40
|
+
end
|
41
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
module HasAttribute
|
2
|
+
module Generators
|
3
|
+
class MigrationGenerator < Rails::Generators::Base
|
4
|
+
desc "Builds the migration for preferences table"
|
5
|
+
|
6
|
+
def create_migration_file
|
7
|
+
migration_template "migration.rb", "db/migrate/create_preferences.rb"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class CreatePreferences < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :preferences do |t|
|
4
|
+
t.string :name, :null => false
|
5
|
+
t.references :owner, :polymorphic => true, :null => false
|
6
|
+
t.references :group, :polymorphic => true
|
7
|
+
t.string :value
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
add_index :preferences, [:owner_id, :owner_type, :name, :group_id, :group_type], :unique => true, :name => 'preferences_owner_id_owner_type_name_group_id_group_type'
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rails/generators/named_base'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
require 'rails/generators/active_model'
|
4
|
+
|
5
|
+
require 'generators/helpers/migration_helper'
|
6
|
+
|
7
|
+
module HasPreference
|
8
|
+
module Generators
|
9
|
+
class Base < Rails::Generators::Base
|
10
|
+
include Rails3Generators::MigrationHelper
|
11
|
+
#include Rails::Generators::Migration
|
12
|
+
|
13
|
+
def self.source_root
|
14
|
+
@_has_preference_source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'has_preference', generator_name, 'templates'))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'generators/has_preference'
|
2
|
+
|
3
|
+
module HasPreference
|
4
|
+
module Generators
|
5
|
+
class MigrationGenerator < Base
|
6
|
+
desc "Builds the migration for preferences table"
|
7
|
+
|
8
|
+
def create_migration_file
|
9
|
+
migration_template "migration.rb", "db/migrate/create_preferences.rb"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class CreatePreferences < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :preferences do |t|
|
4
|
+
t.string :name, :null => false
|
5
|
+
t.references :owner, :polymorphic => true, :null => false
|
6
|
+
t.references :group, :polymorphic => true
|
7
|
+
t.string :value
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
add_index :preferences, [:owner_id, :owner_type, :name, :group_id, :group_type], :unique => true, :name => 'preferences_owner_id_owner_type_name_group_id_group_type'
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,361 @@
|
|
1
|
+
# Created by Thomas Boerger on 2011-07-01.
|
2
|
+
# Copyright (c) 2011. All rights reserved.
|
3
|
+
|
4
|
+
module HasPreference
|
5
|
+
module MacroMethods
|
6
|
+
def has_preference(name, *args)
|
7
|
+
unless included_modules.include?(InstanceMethods)
|
8
|
+
class_inheritable_hash :preference_definitions
|
9
|
+
self.preference_definitions = {}
|
10
|
+
|
11
|
+
has_many :stored_preferences, :as => :owner, :class_name => 'Preference'
|
12
|
+
|
13
|
+
after_save :update_preferences
|
14
|
+
|
15
|
+
named_scope :with_preferences, lambda {|preferences| build_preference_scope(preferences)}
|
16
|
+
named_scope :without_preferences, lambda {|preferences| build_preference_scope(preferences, true)}
|
17
|
+
|
18
|
+
extend HasPreference::ClassMethods
|
19
|
+
include HasPreference::InstanceMethods
|
20
|
+
end
|
21
|
+
|
22
|
+
name = name.to_s
|
23
|
+
|
24
|
+
definition = HasPreference::Definition.new(name, *args)
|
25
|
+
self.preference_definitions[name] = definition
|
26
|
+
|
27
|
+
name = name.gsub(/[^A-Za-z0-9_-]/, '').underscore
|
28
|
+
|
29
|
+
define_method("preferred_#{name}?") do |*group|
|
30
|
+
preferred?(name, group.first)
|
31
|
+
end
|
32
|
+
|
33
|
+
alias_method "prefers_#{name}?", "preferred_#{name}?"
|
34
|
+
|
35
|
+
define_method("preferred_#{name}") do |*group|
|
36
|
+
preferred(name, group.first)
|
37
|
+
end
|
38
|
+
|
39
|
+
alias_method "prefers_#{name}", "preferred_#{name}"
|
40
|
+
|
41
|
+
define_method("preferred_#{name}=") do |*args|
|
42
|
+
write_preference(*args.flatten.unshift(name))
|
43
|
+
end
|
44
|
+
|
45
|
+
alias_method "prefers_#{name}=", "preferred_#{name}="
|
46
|
+
|
47
|
+
define_method("preferred_#{name}_changed?") do |*group|
|
48
|
+
preference_changed?(name, group.first)
|
49
|
+
end
|
50
|
+
|
51
|
+
alias_method "prefers_#{name}_changed?", "preferred_#{name}_changed?"
|
52
|
+
|
53
|
+
define_method("preferred_#{name}_was") do |*group|
|
54
|
+
preference_was(name, group.first)
|
55
|
+
end
|
56
|
+
|
57
|
+
alias_method "prefers_#{name}_was", "preferred_#{name}_was"
|
58
|
+
|
59
|
+
define_method("preferred_#{name}_change") do |*group|
|
60
|
+
preference_change(name, group.first)
|
61
|
+
end
|
62
|
+
|
63
|
+
alias_method "prefers_#{name}_change", "preferred_#{name}_change"
|
64
|
+
|
65
|
+
define_method("preferred_#{name}_will_change!") do |*group|
|
66
|
+
preference_will_change!(name, group.first)
|
67
|
+
end
|
68
|
+
|
69
|
+
alias_method "prefers_#{name}_will_change!", "preferred_#{name}_will_change!"
|
70
|
+
|
71
|
+
define_method("reset_preferred_#{name}!") do |*group|
|
72
|
+
reset_preference!(name, group.first)
|
73
|
+
end
|
74
|
+
|
75
|
+
alias_method "reset_prefers_#{name}!", "reset_preferred_#{name}!"
|
76
|
+
|
77
|
+
definition
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
module ClassMethods
|
82
|
+
def build_preference_scope(preferences, inverse = false)
|
83
|
+
joins = []
|
84
|
+
statements = []
|
85
|
+
values = []
|
86
|
+
|
87
|
+
preferences = preferences.inject({}) do |result, (group, value)|
|
88
|
+
if value.is_a?(Hash)
|
89
|
+
value.each {|preference, value| result[[group, preference]] = value}
|
90
|
+
else
|
91
|
+
result[[nil, group]] = value
|
92
|
+
end
|
93
|
+
|
94
|
+
result
|
95
|
+
end
|
96
|
+
|
97
|
+
preferences.each do |(group, preference), value|
|
98
|
+
group_id, group_type = Preference.split_group(group)
|
99
|
+
|
100
|
+
preference = preference.to_s
|
101
|
+
definition = preference_definitions[preference.to_s]
|
102
|
+
|
103
|
+
value = definition.type_cast(value)
|
104
|
+
is_default = definition.default_value(group_type) == value
|
105
|
+
|
106
|
+
table = "preferences_#{group_id}_#{group_type}_#{preference}"
|
107
|
+
|
108
|
+
joins << "LEFT JOIN preferences AS #{table} ON #{table}.owner_id = #{table_name}.#{primary_key} AND " + sanitize_sql(
|
109
|
+
"#{table}.owner_type" => base_class.name.to_s,
|
110
|
+
"#{table}.group_id" => group_id,
|
111
|
+
"#{table}.group_type" => group_type,
|
112
|
+
"#{table}.name" => preference
|
113
|
+
)
|
114
|
+
|
115
|
+
if inverse
|
116
|
+
statements << "#{table}.id IS NOT NULL AND #{table}.value " + (value.nil? ? ' IS NOT NULL' : ' != ?') + (!is_default ? " OR #{table}.id IS NULL" : '')
|
117
|
+
else
|
118
|
+
statements << "#{table}.id IS NOT NULL AND #{table}.value " + (value.nil? ? ' IS NULL' : ' = ?') + (is_default ? " OR #{table}.id IS NULL" : '')
|
119
|
+
end
|
120
|
+
|
121
|
+
values << value unless value.nil?
|
122
|
+
end
|
123
|
+
|
124
|
+
sql = statements.map! {|statement| "(#{statement})"} * ' AND '
|
125
|
+
{ :joins => joins, :conditions => values.unshift(sql) }
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
module InstanceMethods
|
130
|
+
def preferences(group = nil)
|
131
|
+
preferences = preferences_group(group)
|
132
|
+
|
133
|
+
unless preferences_group_loaded?(group)
|
134
|
+
group_id, group_type = Preference.split_group(group)
|
135
|
+
|
136
|
+
find_preferences(:group_id => group_id, :group_type => group_type).each do |preference|
|
137
|
+
preferences[preference.name] = preference.value unless preferences.include?(preference.name)
|
138
|
+
end
|
139
|
+
|
140
|
+
preference_definitions.each do |name, definition|
|
141
|
+
preferences[name] = definition.default_value(group_type) unless preferences.include?(name)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
preferences.inject({}) do |typed_preferences, (name, value)|
|
146
|
+
typed_preferences[name] = value.nil? ? value : preference_definitions[name].type_cast(value)
|
147
|
+
typed_preferences
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def preferred?(name, group = nil)
|
152
|
+
name = name.to_s
|
153
|
+
assert_valid_preference(name)
|
154
|
+
|
155
|
+
value = preferred(name, group)
|
156
|
+
preference_definitions[name].query(value)
|
157
|
+
end
|
158
|
+
|
159
|
+
alias_method :prefers?, :preferred?
|
160
|
+
|
161
|
+
def preferred(name, group = nil)
|
162
|
+
name = name.to_s
|
163
|
+
assert_valid_preference(name)
|
164
|
+
|
165
|
+
if preferences_group(group).include?(name)
|
166
|
+
value = preferences_group(group)[name]
|
167
|
+
else
|
168
|
+
group_id, group_type = Preference.split_group(group)
|
169
|
+
preference = find_preferences(:name => name, :group_id => group_id, :group_type => group_type).first unless preferences_group_loaded?(group)
|
170
|
+
|
171
|
+
value = preference ? preference.value : preference_definitions[name].default_value(group_type)
|
172
|
+
preferences_group(group)[name] = value
|
173
|
+
end
|
174
|
+
|
175
|
+
definition = preference_definitions[name]
|
176
|
+
value = definition.type_cast(value) unless value.nil?
|
177
|
+
|
178
|
+
value
|
179
|
+
end
|
180
|
+
|
181
|
+
alias_method :prefers, :preferred
|
182
|
+
|
183
|
+
def write_preference(name, value, group = nil)
|
184
|
+
name = name.to_s
|
185
|
+
assert_valid_preference(name)
|
186
|
+
|
187
|
+
preferences_changed = preferences_changed_group(group)
|
188
|
+
|
189
|
+
if preferences_changed.include?(name)
|
190
|
+
old = preferences_changed[name]
|
191
|
+
preferences_changed.delete(name) unless preference_value_changed?(name, old, value)
|
192
|
+
else
|
193
|
+
old = clone_preference_value(name, group)
|
194
|
+
preferences_changed[name] = old if preference_value_changed?(name, old, value)
|
195
|
+
end
|
196
|
+
|
197
|
+
value = convert_number_column_value(value) if preference_definitions[name].number?
|
198
|
+
preferences_group(group)[name] = value
|
199
|
+
|
200
|
+
value
|
201
|
+
end
|
202
|
+
|
203
|
+
def preferences_changed?(group = nil)
|
204
|
+
!preferences_changed_group(group).empty?
|
205
|
+
end
|
206
|
+
|
207
|
+
def preferences_changed(group = nil)
|
208
|
+
preferences_changed_group(group).keys
|
209
|
+
end
|
210
|
+
|
211
|
+
def preference_changes(group = nil)
|
212
|
+
preferences_changed(group).inject({}) do |changes, preference|
|
213
|
+
changes[preference] = preference_change(preference, group)
|
214
|
+
changes
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def reload(*args) #:nodoc:
|
219
|
+
result = super
|
220
|
+
|
221
|
+
@preferences.clear if @preferences
|
222
|
+
@preferences_changed.clear if @preferences_changed
|
223
|
+
|
224
|
+
result
|
225
|
+
end
|
226
|
+
|
227
|
+
private
|
228
|
+
def assert_valid_preference(name)
|
229
|
+
raise(ArgumentError, "Unknown preference: #{name}") unless preference_definitions.include?(name)
|
230
|
+
end
|
231
|
+
|
232
|
+
def preferences_group(group)
|
233
|
+
@preferences ||= {}
|
234
|
+
@preferences[group.is_a?(Symbol) ? group.to_s : group] ||= {}
|
235
|
+
end
|
236
|
+
|
237
|
+
def preferences_group_loaded?(group)
|
238
|
+
preference_definitions.length == preferences_group(group).length
|
239
|
+
end
|
240
|
+
|
241
|
+
def clone_preference_value(name, group)
|
242
|
+
value = preferred(name, group)
|
243
|
+
value.duplicable? ? value.clone : value
|
244
|
+
rescue TypeError, NoMethodError
|
245
|
+
value
|
246
|
+
end
|
247
|
+
|
248
|
+
def preferences_changed_group(group)
|
249
|
+
@preferences_changed ||= {}
|
250
|
+
@preferences_changed[group.is_a?(Symbol) ? group.to_s : group] ||= {}
|
251
|
+
end
|
252
|
+
|
253
|
+
def preference_changed?(name, group)
|
254
|
+
preferences_changed_group(group).include?(name)
|
255
|
+
end
|
256
|
+
|
257
|
+
def preference_change(name, group)
|
258
|
+
[preferences_changed_group(group)[name], preferred(name, group)] if preference_changed?(name, group)
|
259
|
+
end
|
260
|
+
|
261
|
+
def preference_was(name, group)
|
262
|
+
preference_changed?(name, group) ? preferences_changed_group(group)[name] : preferred(name, group)
|
263
|
+
end
|
264
|
+
|
265
|
+
def preference_will_change!(name, group)
|
266
|
+
preferences_changed_group(group)[name] = clone_preference_value(name, group)
|
267
|
+
end
|
268
|
+
|
269
|
+
def reset_preference!(name, group)
|
270
|
+
write_preference(name, preferences_changed_group(group)[name], group) if preference_changed?(name, group)
|
271
|
+
end
|
272
|
+
|
273
|
+
def preference_value_changed?(name, old, value)
|
274
|
+
definition = preference_definitions[name]
|
275
|
+
|
276
|
+
if definition.type == :integer && (old.nil? || old == 0)
|
277
|
+
value = nil if value.blank?
|
278
|
+
else
|
279
|
+
value = definition.type_cast(value)
|
280
|
+
end
|
281
|
+
|
282
|
+
old != value
|
283
|
+
end
|
284
|
+
|
285
|
+
def update_preferences
|
286
|
+
if @preferences_changed
|
287
|
+
@preferences_changed.each do |group, preferences|
|
288
|
+
group_id, group_type = Preference.split_group(group)
|
289
|
+
|
290
|
+
preferences.keys.each do |name|
|
291
|
+
attributes = {:name => name, :group_id => group_id, :group_type => group_type}
|
292
|
+
|
293
|
+
preference = find_preferences(attributes).first || stored_preferences.build(attributes)
|
294
|
+
preference.value = preferred(name, group)
|
295
|
+
|
296
|
+
preference.save!
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
@preferences_changed.clear
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
def find_preferences(attributes)
|
305
|
+
if stored_preferences.loaded?
|
306
|
+
stored_preferences.select do |preference|
|
307
|
+
attributes.all? {|attribute, value| preference[attribute] == value}
|
308
|
+
end
|
309
|
+
else
|
310
|
+
stored_preferences.find(:all, :conditions => attributes)
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
class Definition
|
316
|
+
attr_reader :type
|
317
|
+
|
318
|
+
def initialize(name, *args)
|
319
|
+
options = args.extract_options!
|
320
|
+
options.assert_valid_keys(:default, :group_defaults)
|
321
|
+
|
322
|
+
@type = args.first ? args.first.to_sym : :boolean
|
323
|
+
@column = ActiveRecord::ConnectionAdapters::Column.new(name.to_s, options[:default], @type == :any ? nil : @type.to_s)
|
324
|
+
|
325
|
+
@group_defaults = (options[:group_defaults] || {}).inject({}) do |defaults, (group, default)|
|
326
|
+
defaults[group.is_a?(Symbol) ? group.to_s : group] = type_cast(default)
|
327
|
+
defaults
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
def name
|
332
|
+
@column.name
|
333
|
+
end
|
334
|
+
|
335
|
+
def default_value(group = nil)
|
336
|
+
@group_defaults.include?(group) ? @group_defaults[group] : @column.default
|
337
|
+
end
|
338
|
+
|
339
|
+
def number?
|
340
|
+
@column.number?
|
341
|
+
end
|
342
|
+
|
343
|
+
def type_cast(value)
|
344
|
+
@type == :any ? value : @column.type_cast(value)
|
345
|
+
end
|
346
|
+
|
347
|
+
def query(value)
|
348
|
+
if !(value = type_cast(value))
|
349
|
+
false
|
350
|
+
elsif number?
|
351
|
+
!value.zero?
|
352
|
+
else
|
353
|
+
!value.blank?
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
ActiveRecord::Base.class_eval do
|
360
|
+
extend HasPreference::MacroMethods
|
361
|
+
end
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: has_preference
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Thomas Boerger
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-07-01 00:00:00 Z
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Preference for ActiveRecord models
|
22
|
+
email: tboerger@tbpro.de
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files:
|
28
|
+
- README
|
29
|
+
- LICENSE
|
30
|
+
files:
|
31
|
+
- LICENSE
|
32
|
+
- README
|
33
|
+
- Rakefile
|
34
|
+
- init.rb
|
35
|
+
- app/models/preference.rb
|
36
|
+
- lib/generators/has_attribute/migration_generator.rb
|
37
|
+
- lib/generators/has_attribute/template/migration.rb
|
38
|
+
- lib/generators/has_preference/migration/migration_generator.rb
|
39
|
+
- lib/generators/has_preference/migration/templates/migration.rb
|
40
|
+
- lib/generators/has_preference.rb
|
41
|
+
- lib/has_preference.rb
|
42
|
+
homepage: http://github.com/tbpro/has_preference
|
43
|
+
licenses: []
|
44
|
+
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options:
|
47
|
+
- --line-numbers
|
48
|
+
- --main=README
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
hash: 3
|
66
|
+
segments:
|
67
|
+
- 0
|
68
|
+
version: "0"
|
69
|
+
requirements: []
|
70
|
+
|
71
|
+
rubyforge_project:
|
72
|
+
rubygems_version: 1.7.2
|
73
|
+
signing_key:
|
74
|
+
specification_version: 3
|
75
|
+
summary: Has preference
|
76
|
+
test_files: []
|
77
|
+
|