smart_list 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/lib/add_order_bit.rb +10 -0
- data/lib/smart_list.rb +204 -0
- metadata +47 -0
data/lib/smart_list.rb
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
require "smart_list"
|
4
|
+
require "add_order_bit"
|
5
|
+
require "smart_list_helper"
|
6
|
+
require "digest/sha1"
|
7
|
+
|
8
|
+
$active_smart_lists = {}
|
9
|
+
|
10
|
+
module SmartList
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
base.extend ClassMethods
|
14
|
+
end
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
def smart_list(options = {:order_bit => "order_bit", :group => nil, :scope_conditions => nil})
|
18
|
+
# Check if order_bit exists
|
19
|
+
options[:order_bit] ||= "order_bit"
|
20
|
+
options[:fixed] ||= false
|
21
|
+
if self.column_names.index(options[:order_bit].to_s).nil?
|
22
|
+
::AddOrderBit.add_to_table(self.table_name)
|
23
|
+
else
|
24
|
+
unless is_smart_list?
|
25
|
+
cattr_accessor :group_col, :order_bit_name, :base_class, :fixed_list
|
26
|
+
send :include, InstanceMethods
|
27
|
+
|
28
|
+
$active_smart_lists.merge!(Digest::SHA1.hexdigest(self.name) => self.name)
|
29
|
+
end
|
30
|
+
self.send(:default_scope, :order => "#{options[:order_bit].to_s} ASC")
|
31
|
+
self.send(:before_create, :set_order_bit)
|
32
|
+
self.group_col = (options[:group].to_sym) rescue nil
|
33
|
+
self.order_bit_name = options[:order_bit].to_sym
|
34
|
+
self.base_class = options[:base_class].constantize rescue self.name.constantize
|
35
|
+
self.fixed_list = options[:fixed]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def grouped_list(group_name)
|
40
|
+
if self.group_col.nil? || self.group_col.blank?
|
41
|
+
self.find(:all)
|
42
|
+
else
|
43
|
+
self.find(:all, :conditions => {self.group_col => group_name})
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def groups
|
48
|
+
if self.group_col.nil? || self.group_col.blank?
|
49
|
+
raise "This is not a grouped list - use options[:group] set colummn to group lists"
|
50
|
+
else
|
51
|
+
puts self.group_col.inspect
|
52
|
+
self.find(:all, :group => self.group_col).map {|x| x.group_name }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def group_list
|
57
|
+
self.groups.map {|group| self.find(:all, :conditions => {self.group_col => group})}
|
58
|
+
end
|
59
|
+
|
60
|
+
def is_smart_list?
|
61
|
+
self.included_modules.include?(InstanceMethods)
|
62
|
+
end
|
63
|
+
|
64
|
+
def reorder_group(group_name, options = {:order_by => :created_at})
|
65
|
+
if self.group_col.nil? || self.group_col.blank?
|
66
|
+
raise "Only grouped lists could be reordered"
|
67
|
+
else
|
68
|
+
transaction do
|
69
|
+
group = self.grouped_list(group_name)
|
70
|
+
order_mode = options[:order_by].to_s
|
71
|
+
ordered = group.sort_by {|item| item.send(order_mode)}
|
72
|
+
ordered.each_with_index do |item, i|
|
73
|
+
item[self.base_class.order_bit_name] = AddOrderBit::ORDER_BIT_DEFAULT+i
|
74
|
+
item.send(:update_without_callbacks)
|
75
|
+
end
|
76
|
+
|
77
|
+
new_group = self.grouped_list(group_name).map {|item| item.id}
|
78
|
+
if new_group == ordered.map {|item| item.id}
|
79
|
+
return true
|
80
|
+
else
|
81
|
+
raise ActiveRecord::Rollback
|
82
|
+
return false
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
module InstanceMethods
|
90
|
+
def move_up!
|
91
|
+
if self.base_class.fixed_list == false
|
92
|
+
unless self.order_position == 0
|
93
|
+
old_pos = self.order_bit_pos
|
94
|
+
pre_item = self.pre
|
95
|
+
if old_pos != pre_item.order_bit_pos
|
96
|
+
self.update_attributes(self.base_class.order_bit_name => pre_item.order_bit_pos)
|
97
|
+
pre_item.update_attributes(self.base_class.order_bit_name => old_pos)
|
98
|
+
else
|
99
|
+
self.update_attributes(self.base_class.order_bit_name => old_pos-1)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def move_down!
|
106
|
+
if self.base_class.fixed_list == false
|
107
|
+
if self.base_class.group_col.nil?
|
108
|
+
all = self.base_class.find(:all)
|
109
|
+
else
|
110
|
+
all = self.base_class.find(:all, :conditions => {self.base_class.group_col => self.send(self.base_class.group_col)})
|
111
|
+
end
|
112
|
+
unless self.order_position == all.size-1
|
113
|
+
old_pos = self.order_bit_pos
|
114
|
+
post_item = self.post
|
115
|
+
if old_pos != post_item.order_bit_pos
|
116
|
+
self.update_attributes(self.base_class.order_bit_name => post_item.order_bit_pos)
|
117
|
+
post_item.update_attributes(self.base_class.order_bit_name => old_pos)
|
118
|
+
else
|
119
|
+
self.update_attributes(self.base_class.order_bit_name => old_pos+1)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def group_list_items(conditions = {})
|
126
|
+
if self.base_class.group_col.nil? || self.base_class.group_col.blank?
|
127
|
+
self.base_class.find(:all)
|
128
|
+
else
|
129
|
+
self.base_class.find_by_sql("SELECT * from #{self.base_class.table_name} where #{self.base_class.group_col} = '#{self[self.base_class.group_col].to_s}' order by #{self.base_class.order_bit_name} ASC")
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Previos Item
|
134
|
+
def pre
|
135
|
+
pos = (self.order_position == 0 ? 0 : (self.order_position - 1 rescue 0))
|
136
|
+
all = self.group_list_items[pos]
|
137
|
+
end
|
138
|
+
|
139
|
+
# Next Item
|
140
|
+
def post
|
141
|
+
all = self.group_list_items
|
142
|
+
pos = (self.order_position == all.size-1 ? self.order_position : self.order_position + 1)
|
143
|
+
all[pos]
|
144
|
+
end
|
145
|
+
|
146
|
+
def order_position
|
147
|
+
all = self.group_list_items.map {|x| x.id}
|
148
|
+
all.index(self.id)
|
149
|
+
end
|
150
|
+
|
151
|
+
def order_bit_pos
|
152
|
+
self.attributes[self.base_class.order_bit_name.to_s]
|
153
|
+
end
|
154
|
+
|
155
|
+
def group_name
|
156
|
+
if self.base_class.group_col.nil?
|
157
|
+
""
|
158
|
+
else
|
159
|
+
self.send(self.base_class.group_col.to_s)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def set_order_bit
|
164
|
+
if self.base_class.fixed_list == false
|
165
|
+
self[self.base_class.order_bit_name] = self.base_class.last[self.base_class.order_bit_name] + 1 rescue 100
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def followers(options = {})
|
170
|
+
if self.base_class.group_col.nil?
|
171
|
+
self.base_class.find_by_sql("SELECT * from #{self.base_class.table_name} where #{self.base_class.order_bit_name} #{options[:include_self] == true ? '>=' : '>'} #{self.order_bit}")
|
172
|
+
else
|
173
|
+
self.base_class.find_by_sql("SELECT * from #{self.base_class.table_name} where #{self.base_class.order_bit_name} #{options[:include_self] == true ? '>=' : '>'} #{self.order_bit} and #{self.base_class.group_col.to_s} = '#{self.group_name}'")
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def previous_items(options = {})
|
178
|
+
if self.base_class.group_col.nil?
|
179
|
+
self.base_class.find_by_sql("SELECT * from #{self.base_class.table_name} where #{self.base_class.order_bit_name} #{options[:include_self] == true ? '<=' : '<'} #{self.order_bit}")
|
180
|
+
else
|
181
|
+
self.base_class.find_by_sql("SELECT * from #{self.base_class.table_name} where #{self.base_class.order_bit_name} #{options[:include_self] == true ? '<=' : '<'} #{self.order_bit} and #{self.base_class.group_col.to_s} = '#{self.group_name}'")
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def class_name_sha
|
186
|
+
Digest::SHA1(self.class.name)
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
class Engine < Rails::Engine
|
192
|
+
end
|
193
|
+
|
194
|
+
SmartList::Engine.routes.draw do
|
195
|
+
get "/smart_list/move_up/:type/:id", :controller => "smart_list", :action => "move_up"
|
196
|
+
get "/smart_list/move_down/:type/:id", :controller => "smart_list", :action => "move_down"
|
197
|
+
end
|
198
|
+
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
ActiveRecord::Base.send(:include, SmartList)
|
203
|
+
ActionController::Base.helper SmartListHelper
|
204
|
+
|
metadata
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: smart_list
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Florian Eck
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-03-11 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Easy to use list behavior for ActiveRecord models, includes grouping
|
15
|
+
of items by column content, order, reorder and helpers for ActionView
|
16
|
+
email: it-support@friends-systems.de
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/smart_list.rb
|
22
|
+
- lib/add_order_bit.rb
|
23
|
+
homepage: https://github.com/florianeck/smart_list
|
24
|
+
licenses: []
|
25
|
+
post_install_message:
|
26
|
+
rdoc_options: []
|
27
|
+
require_paths:
|
28
|
+
- lib
|
29
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - ! '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
requirements: []
|
42
|
+
rubyforge_project:
|
43
|
+
rubygems_version: 1.8.25
|
44
|
+
signing_key:
|
45
|
+
specification_version: 3
|
46
|
+
summary: List-style behavior for ActiveRecordt
|
47
|
+
test_files: []
|