is_listable 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
@@ -0,0 +1,5 @@
1
+ == 0.0.3
2
+
3
+ Added the ability to add permalinks with is_listable. Before this version, it would have conflicted since it's looking
4
+ for the id. If you are calling, for example Post.find_by_permalink() this would be an issue. So what you can do now is this:
5
+ is_listable :permalink => "my_permalink_attribute"
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Michael van Rooijen
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.
@@ -0,0 +1,176 @@
1
+ = Is Listable
2
+
3
+ "Is Listable" is a gem that provides a way to implement a simple listing method by using generated view helpers to create up and down buttons.
4
+ This will allow you to very quickly get the "Move Up" and "Move Down" button functionality to move your database records up and down in order.
5
+
6
+ This plugin depends on the acts_as_list plugin. I have created a gem version out of it for convenience when installing this gem.
7
+
8
+ == Installation
9
+
10
+ === Add Repository Source(s)
11
+
12
+ gem sources -a http://gemcutter.org
13
+ gem sources -a http://gems.github.com
14
+
15
+ === Gem
16
+
17
+ # Gem Cutter
18
+ sudo gem install is_listable
19
+
20
+ # GitHub
21
+ sudo gem install meskyanichi-is_listable
22
+
23
+ === Plugin
24
+
25
+ ./script/plugin install git://github.com/meskyanichi/is_listable.git
26
+
27
+
28
+ == Simple Setup
29
+
30
+ ==== Initializing the gems inside "environment.rb"
31
+
32
+ # For GemCutter Version
33
+ config.gem "is_listable", :lib => "is_listable", :source => 'http://gemcutter.org'
34
+ config.gem "acts_as_list", :lib => "acts_as_list", :source => 'http://gemcutter.org'
35
+
36
+ # For GitHub Version
37
+ config.gem "meskyanichi-is_listable", :lib => "is_listable", :source => 'http://gems.github.com'
38
+ config.gem "acts_as_list", :lib => "acts_as_list", :source => 'http://gemcutter.org'
39
+
40
+ ==== PostModel
41
+ class Post < ActiveRecord::Base
42
+ acts_as_list
43
+ end
44
+
45
+ ==== PostsController
46
+ class PostsController < ApplicationController
47
+ is_listable
48
+ end
49
+
50
+ ==== PostsController#index
51
+ <table>
52
+ <tr>
53
+ <th colspan="2">Position</th>
54
+ <th>Name</th>
55
+ </tr>
56
+ <% @posts.each do |post| %>
57
+ <tr>
58
+ <td><%= up_button_for_posts(post)</td>
59
+ <td><%= down_button_for_posts(post)</td>
60
+ <td><%= post.name %></td>
61
+ </tr>
62
+ <% end %>
63
+ </table>
64
+
65
+ This is basically all it takes to already get the gems working their magic.
66
+ This will by default assume the posts table in the database has a "position" column which will determine the records position.
67
+
68
+
69
+ == Additional Options
70
+
71
+ Here's what additional options you can pass to the methods provided by the Is Listable gem.
72
+
73
+ === is_listable
74
+
75
+ The is_listable method takes a hash of options. These are the following options you can provide:
76
+
77
+ - :column (default: 'position')
78
+ - :controller (default: the invoked methods' controller name)
79
+ - :model (default: the invoked methods' controller name, pluralized and camelcased)
80
+ - :scope (default: nil)
81
+ - :redirect_to (default: :back)
82
+
83
+ View the implementation examples below:
84
+
85
+ ==== :column
86
+ Specify the column name that represents the position in the database
87
+ class PostsController < ApplicationController
88
+ is_listable :column => 'position'
89
+ end
90
+
91
+
92
+ ==== :controller
93
+ Specify the controller name which the is_listable should be invoked on.
94
+ 99% of the time you do not need to provide it, as the is_listable method knows what controller invoked it.
95
+ class PostsController < ApplicationController
96
+ is_listable :controller => "posts"
97
+ end
98
+
99
+
100
+ ==== :model
101
+ Specify the model name which the is_listable should be invoked on.
102
+ By default it will try to use (in this case) the Post model, since it's the singular and camelcased "posts".
103
+ If Post is not the model you wish to the PostController make listable, just provide the :model hash value of the
104
+ model you would like to sort.
105
+ class PostsController < ApplicationController
106
+ is_listable :model => "Post"
107
+ end
108
+
109
+
110
+ ==== :scope
111
+ Pass in an ActiveRecord object that's associated to the model.
112
+ It is mainly to prevent user's from haxing the web app and then updating
113
+ other users' record position. So this is a very simple solution that'll prevent it from happening.
114
+ class PostsController < ApplicationController
115
+ is_listable :scope => current_user
116
+ end
117
+
118
+
119
+ ==== :redirect_to
120
+ This option will allow you to specify a location to redirect to after the sort process has completed.
121
+ By default it will redirect back to the page the request came from.
122
+ class PostsController < ApplicationController
123
+ is_listable :redirect_to => {:controller => "posts", :action => "index"}
124
+ end
125
+
126
+
127
+ ==== :permalink
128
+ Let's say that you are using permalinks to allow pretty URL's. This would normally conflict since is_listable only accepts
129
+ objects as a parameter in the view helpers that are provided. However, the :permalink option will fix this problem! If you
130
+ are using, for example, the plugin "permalink_fu" and let it handle the creation of permalinks, you will most likely have permalinks
131
+ stored in the "permalink" attribute inside your database. If this is the case, you can let is_listable work together with it like so.
132
+ Note: Of course, if the permalink attribute inside the database is called, for example, "perm", you just replace the string "permalink" with "perm".
133
+ class PostsController < ApplicationController
134
+ is_listable :permalink => "permalink"
135
+ end
136
+
137
+
138
+ === up_button_for_object and down_button_for_object
139
+
140
+ Once the is_listable method is invoked on a controller, it will generate two view helpers which will be available to all views.
141
+ This is a very simple implementation, and the arguments taken are similar to those of the link_to and button_to methods provided by Rails.
142
+
143
+ up_button_for_posts(post, options)
144
+
145
+ The first argument you must provide, should be the ActiveRecord object that's, for example, currently inside a @objects.each loop.
146
+ The second argument takes a hash of options. Like the link_to() and button_to() they will accept "url" and "html" attributes.
147
+
148
+ up_button_for_posts(post, {
149
+ :url => { :controller => 'posts , :action => 'position', :direction => 'higher', :id => post},
150
+ :html => { :id => "posts_up_button_#{post.id}", :class => "posts_up_button" }
151
+ })
152
+
153
+ So like the example above, you can add any additional, or overwrite existing attributes/options inside the second argument as a hash.
154
+ Note that, by default, the view helpers will automatically render out the id/class attributes on the html button tag the same as in the example above. So you can easily apply styles to the provided classes and perform javascript calls on these unique ids namings.
155
+
156
+ down_button_for_posts(post, {
157
+ :url => { :controller => 'posts , :action => 'position', :direction => 'lower', :id => post},
158
+ :html => { :id => "posts_down_button_#{post.id}", :class => "posts_down_button" }
159
+ })
160
+
161
+ So the work is basically done unless you are trying to accomplish something a little more complex that the defaults do not provide.
162
+ But, usually this is not the case and you can just call the simple method like so:
163
+
164
+ up_button_for_posts(post)
165
+
166
+ However, what you might want to change frequently is the name/label of the button. By default the up_button_for_objects and the down_button_for_objects will either name the button "up" or "down" depending on which was called. To overwrite the defaults, you simply provide a name key/value of "name" like so:
167
+
168
+ up_button_for_posts(post, :name => "Move Up")
169
+
170
+ This will change the "Up" label to "Move Up".
171
+
172
+
173
+
174
+ == Copyright
175
+
176
+ Copyright (c) 2009 Michael van Rooijen. See LICENSE for details.
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "is_listable"
8
+ gem.summary = "\"Is Listable\" is a gem that provides a way to implement a simple listing method by using generated view helpers to create up and down buttons."
9
+ gem.description = "This will allow you to very quickly get the \"Move Up\" and \"Move Down\" button functionality to move your database records up and down in order. "
10
+ gem.email = "meskyan@gmail.com"
11
+ gem.homepage = "http://github.com/meskyanichi/is_listable"
12
+ gem.authors = ["Michael van Rooijen"]
13
+ gem.add_dependency('acts_as_list')
14
+ gem.files.include 'lib/*'
15
+ end
16
+ rescue LoadError
17
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
18
+ end
19
+
20
+ require 'rake/testtask'
21
+ Rake::TestTask.new(:test) do |test|
22
+ test.libs << 'lib' << 'test'
23
+ test.pattern = 'test/**/*_test.rb'
24
+ test.verbose = true
25
+ end
26
+
27
+ begin
28
+ require 'rcov/rcovtask'
29
+ Rcov::RcovTask.new do |test|
30
+ test.libs << 'test'
31
+ test.pattern = 'test/**/*_test.rb'
32
+ test.verbose = true
33
+ end
34
+ rescue LoadError
35
+ task :rcov do
36
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
37
+ end
38
+ end
39
+
40
+ task :test => :check_dependencies
41
+
42
+ task :default => :test
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ if File.exist?('VERSION')
47
+ version = File.read('VERSION')
48
+ else
49
+ version = ""
50
+ end
51
+
52
+ rdoc.rdoc_dir = 'rdoc'
53
+ rdoc.title = "is_listable #{version}"
54
+ rdoc.rdoc_files.include('README*')
55
+ rdoc.rdoc_files.include('lib/**/*.rb')
56
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.4
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "is_listable"
2
+ ActionController::Base.send :include, IsListable
@@ -0,0 +1,50 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{is_listable}
8
+ s.version = "0.0.4"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Michael van Rooijen"]
12
+ s.date = %q{2009-10-02}
13
+ s.description = %q{This will allow you to very quickly get the "Move Up" and "Move Down" button functionality to move your database records up and down in order. }
14
+ s.email = %q{meskyan@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "CHANGELOG",
23
+ "LICENSE",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "init.rb",
28
+ "is_listable.gemspec",
29
+ "lib/is_listable.rb",
30
+ "lib/is_listable.rb"
31
+ ]
32
+ s.homepage = %q{http://github.com/meskyanichi/is_listable}
33
+ s.rdoc_options = ["--charset=UTF-8"]
34
+ s.require_paths = ["lib"]
35
+ s.rubygems_version = %q{1.3.5}
36
+ s.summary = %q{"Is Listable" is a gem that provides a way to implement a simple listing method by using generated view helpers to create up and down buttons.}
37
+
38
+ if s.respond_to? :specification_version then
39
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
40
+ s.specification_version = 3
41
+
42
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
43
+ s.add_runtime_dependency(%q<acts_as_list>, [">= 0"])
44
+ else
45
+ s.add_dependency(%q<acts_as_list>, [">= 0"])
46
+ end
47
+ else
48
+ s.add_dependency(%q<acts_as_list>, [">= 0"])
49
+ end
50
+ end
@@ -0,0 +1,143 @@
1
+ module IsListable
2
+
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ module ClassMethods
8
+
9
+ # Is Listable
10
+ #
11
+ # Is Listable should be invoked inside a controller and takes a hash of options.
12
+ # This will generate a controller action, based on the name of the column in the database.
13
+ # If the column is named, for example "position", which is the default, then the action inside
14
+ # the controller will be defined as "position". What this also does is it provides two view helpers
15
+ # per controller. If you for example have a controller named "PostsController" then this will generate two
16
+ # view helpers, namely: "up_button_for_posts" and "down_button_for_posts". Both of them take two arguments, of which
17
+ # only the first is required, and asks for the post object for which the button should be generated.
18
+ #
19
+ # Example:
20
+ # up_button_for_posts(post)
21
+ # down_button_for_posts(post)
22
+ #
23
+ # That's the bare minimum for getting the listability to work!
24
+ # By default, the button that will be rendered will already have id and class attributes embedded in them.
25
+ #
26
+ # The above examples would generate these id and class attribute name and values:
27
+ #
28
+ # id => "posts_up_button_1", :class => "posts_up_button"
29
+ # id => "posts_down_button_1", :class => "posts_up_button"
30
+ #
31
+ # So this assists in easy button styling and applying javascript calls on.
32
+ # These attributes can be overwritten by adding options inside the hash
33
+ #
34
+ # up_button_for_posts(post, :url => {}, :html => {})
35
+ #
36
+ # Inside the :url hash attribute you may specify controller, action, id and any custom attributes you may like when using
37
+ # the button_to and link_to helper methods. As the :url hash attribute, you may also specify the :html hash attribute to
38
+ # add additional or overwrite existing html attributes for the html button tag.
39
+ def is_listable(options = {})
40
+
41
+ # Options - Has default values.
42
+ # Can be overwritten by user through the hash-argument
43
+ options = {
44
+ :column => 'position',
45
+ :controller => controller_name,
46
+ :model => controller_name.camelcase.singularize,
47
+ :scope => nil,
48
+ :redirect_to => :back,
49
+ :permalink => nil
50
+ }.update(options)
51
+
52
+ # Include the ActionView::Helpers inside of ActionController::Base
53
+ # This will enable html button parsing
54
+ ActionController::Base.send(:include, ActionView::Helpers)
55
+
56
+ # This will create an action dynamically inside the corresponding controller
57
+ # which the view helpers will link to automatically.
58
+ define_method options[:column] do
59
+ if options[:scope].nil?
60
+ if params[:direction].eql?('higher')
61
+ if options[:permalink].nil?
62
+ Kernel.const_get(options[:model]).find(params[:id]).move_higher
63
+ else
64
+ Kernel.const_get(options[:model]).send("find_by_#{options[:permalink]}", params[:id]).move_higher
65
+ end
66
+ elsif params[:direction].eql?('lower')
67
+ if options[:permalink].nil?
68
+ Kernel.const_get(options[:model]).find(params[:id]).move_lower
69
+ else
70
+ Kernel.const_get(options[:model]).send("find_by_#{options[:permalink]}", params[:id]).move_lower
71
+ end
72
+ end
73
+ else
74
+ if params[:direction].eql?('higher')
75
+ if options[:permalink].nil?
76
+ options[:scope].send(options[:model].underscore.pluralize.to_sym).find(params[:id]).move_higher
77
+ else
78
+ options[:scope].send(options[:model].underscore.pluralize.to_sym).send("find_by_#{options[:permalink]}", params[:id]).move_higher
79
+ end
80
+ elsif params[:direction].eql?('lower')
81
+ if options[:permalink].nil?
82
+ options[:scope].send(options[:model].underscore.pluralize.to_sym).find(params[:id]).move_lower
83
+ else
84
+ options[:scope].send(options[:model].underscore.pluralize.to_sym).send("find_by_#{options[:permalink]}", params[:id]).move_lower
85
+ end
86
+ end
87
+ end
88
+ redirect_to(options[:redirect_to])
89
+ end
90
+
91
+ # Defines the up_button_for_(@controller_name) method
92
+ # This method will be available inside all views inside the whole application
93
+ define_method "up_button_for_#{options[:controller]}" do |object, *method_options|
94
+
95
+ # Set default options and overwrite the existing ones with
96
+ # possible user input
97
+ method_options = {
98
+ :name => 'up',
99
+ :attribute => :id,
100
+ :url => { :controller => options[:controller], :action => options[:column], :id => object, :direction => 'higher' },
101
+ :html => { :id => "#{options[:controller]}_up_button_#{object.id}", :class => "#{options[:controller]}_up_button" }
102
+ }.update(method_options.empty? ? {} : method_options.first)
103
+
104
+
105
+ # Generate the up button
106
+ button_to(method_options[:name], method_options[:url], method_options[:html]) unless object.first?
107
+ end
108
+
109
+ # Defines the down_button_for_(@controller_name) method
110
+ # This method will be available inside all views inside the whole application
111
+ define_method "down_button_for_#{options[:controller]}" do |object, *method_options|
112
+
113
+ # Find the last position of the objects list and store it inside an instance variable
114
+ # This will prevent multiple queries from being executed when the method is invoked
115
+ # from inside a for/each loop. A simple form of variable caching to improve performance.
116
+ if options[:scope].nil?
117
+ @last_position ||= Kernel.const_get(options[:model]).last.send(options[:column].to_sym)
118
+ else
119
+ @last_position ||= options[:scope].send(options[:model].pluralize.underscore.to_sym).last.send(options[:column].to_sym)
120
+ end
121
+
122
+ # Set default options and overwrite the existing ones with
123
+ # possible user input
124
+ method_options = {
125
+ :name => 'down',
126
+ :url => { :controller => options[:controller], :action => options[:column], :id => object, :direction => 'lower' },
127
+ :html => { :id => "#{options[:controller]}_down_button_#{object.id}", :class => "#{options[:controller]}_down_button" }
128
+ }.update(method_options.empty? ? {} : method_options.first)
129
+
130
+ # Generate the down button
131
+ unless object.send(options[:column]).eql?(@last_position)
132
+ button_to(method_options[:name], method_options[:url], method_options[:html])
133
+ end
134
+ end
135
+
136
+ # Makes the methods available to the views
137
+ helper_method "up_button_for_#{options[:controller]}",
138
+ "down_button_for_#{options[:controller]}"
139
+ end
140
+ end
141
+ end
142
+
143
+ ActionController::Base.send :include, IsListable
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: is_listable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Michael van Rooijen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-02 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: acts_as_list
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: "This will allow you to very quickly get the \"Move Up\" and \"Move Down\" button functionality to move your database records up and down in order. "
26
+ email: meskyan@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - LICENSE
33
+ - README.rdoc
34
+ files:
35
+ - .document
36
+ - .gitignore
37
+ - CHANGELOG
38
+ - LICENSE
39
+ - README.rdoc
40
+ - Rakefile
41
+ - VERSION
42
+ - init.rb
43
+ - is_listable.gemspec
44
+ - lib/is_listable.rb
45
+ has_rdoc: true
46
+ homepage: http://github.com/meskyanichi/is_listable
47
+ licenses: []
48
+
49
+ post_install_message:
50
+ rdoc_options:
51
+ - --charset=UTF-8
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ requirements: []
67
+
68
+ rubyforge_project:
69
+ rubygems_version: 1.3.5
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: "\"Is Listable\" is a gem that provides a way to implement a simple listing method by using generated view helpers to create up and down buttons."
73
+ test_files: []
74
+