has_preference 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|