schofield 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/.rvmrc ADDED
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
+ # development environment upon cd'ing into the directory
5
+
6
+ # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional.
7
+ environment_id="ree-1.8.7-2011.03@schofield"
8
+
9
+ #
10
+ # Uncomment following line if you want options to be set only for given project.
11
+ #
12
+ # PROJECT_JRUBY_OPTS=( --1.9 )
13
+
14
+ #
15
+ # First we attempt to load the desired environment directly from the environment
16
+ # file. This is very fast and efficient compared to running through the entire
17
+ # CLI and selector. If you want feedback on which environment was used then
18
+ # insert the word 'use' after --create as this triggers verbose mode.
19
+ #
20
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
21
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
22
+ then
23
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
24
+
25
+ if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]
26
+ then
27
+ . "${rvm_path:-$HOME/.rvm}/hooks/after_use"
28
+ fi
29
+ else
30
+ # If the environment file has not yet been created, use the RVM CLI to select.
31
+ if ! rvm --create use "$environment_id"
32
+ then
33
+ echo "Failed to create RVM environment '${environment_id}'."
34
+ return 1
35
+ fi
36
+ fi
37
+
38
+ #
39
+ # If you use an RVM gemset file to install a list of gems (*.gems), you can have
40
+ # it be automatically loaded. Uncomment the following and adjust the filename if
41
+ # necessary.
42
+ #
43
+ # filename=".gems"
44
+ # if [[ -s "$filename" ]]
45
+ # then
46
+ # rvm gemset import "$filename" | grep -v already | grep -v listed | grep -v complete | sed '/^$/d'
47
+ # fi
48
+
49
+ # If you use bundler, this might be useful to you:
50
+ # if command -v bundle && [[ -s Gemfile ]]
51
+ # then
52
+ # bundle install
53
+ # fi
54
+
55
+ if [[ $- == *i* ]] # check for interactive shells
56
+ then
57
+ echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green
58
+ else
59
+ echo "Using: $GEM_HOME" # don't use colors in interactive shells
60
+ fi
61
+
@@ -1,14 +1,14 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- diff-lcs (1.1.2)
4
+ diff-lcs (1.1.3)
5
5
  git (1.2.5)
6
- jeweler (1.5.1)
6
+ jeweler (1.5.2)
7
7
  bundler (~> 1.0.0)
8
8
  git (>= 1.2.5)
9
9
  rake
10
- rake (0.8.7)
11
- rcov (0.9.9)
10
+ rake (0.9.2.2)
11
+ rcov (0.9.11)
12
12
  rspec (2.1.0)
13
13
  rspec-core (~> 2.1.0)
14
14
  rspec-expectations (~> 2.1.0)
@@ -3,7 +3,7 @@
3
3
  Description goes here.
4
4
 
5
5
  == Contributing to schofield
6
-
6
+
7
7
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
8
8
  * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
9
9
  * Fork the project
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.2
1
+ 0.3.0
@@ -1,31 +1,31 @@
1
1
  module Schofield
2
-
2
+
3
3
  module Generators
4
-
4
+
5
5
  class Association
6
-
6
+
7
7
  ONE_TO_ONE = '1-1'
8
8
  ONE_TO_MANY = '1-*'
9
-
10
-
11
-
9
+
10
+
11
+
12
12
  class << self; attr_accessor :all end
13
13
  @all = []
14
-
14
+
15
15
  def self.reference_parents
16
16
  all.each { |a| a.reference_parent }
17
17
  end
18
-
18
+
19
19
  def self.report
20
20
  all.each { |a| Responses.say a.report }
21
21
  end
22
-
23
-
24
-
22
+
23
+
24
+
25
25
  attr_reader :parent, :child, :parent_name, :child_name , :polymorphic_name
26
26
  attr_writer :nest
27
27
  attr_accessor :cardinality
28
-
28
+
29
29
  def initialize child, parent_name, one_to_one, polymorphic_name=nil
30
30
  @child = child
31
31
  @child_name = child.name
@@ -35,16 +35,16 @@ module Schofield
35
35
  @nest = polymorphic_name.present? && !one_to_one
36
36
  self.class.all << self
37
37
  end
38
-
38
+
39
39
  def nest?
40
40
  @nest
41
41
  end
42
-
42
+
43
43
  def reference_parent
44
44
  @parent = Levels.find(@parent_name)
45
45
  @parent.child_associations << self
46
46
  end
47
-
47
+
48
48
  def report
49
49
  <<-STRING.gsub(/^ {8}/, '')
50
50
  parent: #{@parent.name}
@@ -55,40 +55,40 @@ module Schofield
55
55
  ---
56
56
  STRING
57
57
  end
58
-
58
+
59
59
  def one_to_one?
60
60
  @cardinality == Association::ONE_TO_ONE
61
61
  end
62
-
62
+
63
63
  def one_to_many?
64
64
  @cardinality == Association::ONE_TO_MANY
65
65
  end
66
-
66
+
67
67
  def polymorphic?
68
68
  @polymorphic_name.present?
69
69
  end
70
-
70
+
71
71
  def non_polymorphic?
72
72
  !polymorphic?
73
73
  end
74
-
74
+
75
75
  def polymorphic_one_to_one?
76
76
  polymorphic? && one_to_one?
77
77
  end
78
-
78
+
79
79
  def polymorphic_one_to_many?
80
80
  polymorphic? && one_to_many?
81
81
  end
82
-
82
+
83
83
  def non_polymorphic_one_to_one?
84
84
  non_polymorphic? && one_to_one?
85
85
  end
86
-
86
+
87
87
  def non_polymorphic_one_to_many?
88
88
  non_polymorphic? && one_to_many?
89
89
  end
90
90
 
91
91
  end
92
-
92
+
93
93
  end
94
94
  end
@@ -1,87 +1,104 @@
1
1
  module Schofield
2
-
2
+
3
3
  module Generators
4
-
4
+
5
5
  class Attribute
6
-
6
+
7
7
  ATTACHMENT_IMAGE_NAMES = %w( image thumbnail enlargement photo avatar )
8
-
8
+
9
9
  attr_reader :model_name, :name, :max_number, :max_length, :attachment_name, :type
10
-
11
-
10
+
11
+
12
12
  def initialize column
13
-
13
+
14
14
  if (match_data = column.name.match(/(.+)_file_name$/))
15
15
  @attachment_name = match_data[1]
16
16
  @attachment = true
17
- @image = @attachment_name =~ /#{ATTACHMENT_IMAGE_NAMES.join('|')}/
17
+ @image = !!(@attachment_name =~ /#{ATTACHMENT_IMAGE_NAMES.join('|')}/)
18
18
  end
19
-
19
+
20
20
  if (match_data = column.name.match(/^(.+)_id$/))
21
- @reference = true
22
- @model_name = match_data[1]
21
+ model_name = match_data[1]
22
+ if Levels.exists?(model_name)
23
+ @model_name = model_name
24
+ @reference = true
25
+ end
23
26
  end
24
-
27
+
25
28
  @name = column.name
26
29
  @required = !column.null
27
30
  @type = column.type
28
31
  @max_length = column.type == :string ? column.limit : nil
29
32
  @max_number = column.type == :integer && !@reference ? 256**column.limit / 2 - 1 : nil
30
-
33
+
31
34
  end
32
-
35
+
33
36
  def reference?
34
37
  @reference == true
35
38
  end
36
-
39
+
37
40
  def attachment?
38
41
  @attachment == true
39
42
  end
40
-
43
+
41
44
  def image?
42
- @image == 0
45
+ @image
43
46
  end
44
-
47
+
45
48
  def required?
46
49
  @required && !@attachment
47
50
  end
48
-
51
+
52
+ def validate_presence?
53
+ required? && @name != 'position' && !boolean? && !fingerprint? && @name != 'slug'
54
+ end
55
+
49
56
  def required_attachment?
50
57
  @attachment && @required
51
58
  end
52
-
59
+
53
60
  def text?
54
61
  type == :text
55
62
  end
56
-
63
+
57
64
  def boolean?
58
65
  type == :boolean
59
66
  end
60
-
67
+
61
68
  def actual_name
62
69
  @attachment_name || @model_name || @name
63
70
  end
64
-
71
+
72
+ def fingerprint?
73
+ !!(@name =~ /_fingerprint$/)
74
+ end
75
+
76
+ def accessible_name
77
+ actual_name unless fingerprint? || @name == 'slug'
78
+ end
79
+
65
80
  def to_column
66
81
  "'#{actual_name.humanize}', lambda { |x| " +
67
82
  case
68
- when image? then "image_tag(x.#{@attachment_name}.url(:thumbnail), :alt => '', :class => 'thumbnail')"
83
+ when image? then "image_tag(x.#{@attachment_name}.url(:admin), :alt => '', :class => 'thumbnail')"
69
84
  when attachment? then "link_to('#{actual_name.humanize}', x.#{@attachment_name}.url)"
85
+ when boolean? then "x.#{actual_name} ? '✓' : ''"
70
86
  else "x.#{actual_name}"
71
87
  end + ' }'
72
88
  end
73
-
89
+
74
90
  def weight
75
91
  case
76
- when image? then 1
77
- when @name == 'name' then 2
78
- when @name == 'title' then 3
79
- when reference? then 4
80
- else 5
92
+ when image? then 1
93
+ when @name == 'name' then 2
94
+ when @name == 'title' then 3
95
+ when reference? then 4
96
+ when @name == 'published' then 6
97
+ else 5
81
98
  end
82
99
  end
83
-
100
+
84
101
  end
85
-
102
+
86
103
  end
87
104
  end
@@ -1,87 +1,87 @@
1
1
  module Schofield
2
-
2
+
3
3
  module Generators
4
-
4
+
5
5
  class Attributes
6
-
6
+
7
7
  include Enumerable
8
-
9
-
8
+
9
+
10
10
  def initialize
11
- @attributes = []
12
- @requireds = []
13
- @required_one_to_ones = []
14
- @attachments = []
15
- @required_attachments = []
16
- @max_numbers = {}
17
- @max_lengths = {}
18
- @references = 0
11
+ @attributes = []
12
+ @presence_validateds = []
13
+ @presence_validated_one_to_ones = []
14
+ @attachments = []
15
+ @required_attachments = []
16
+ @accessibles = []
17
+ @max_numbers = {}
18
+ @max_lengths = {}
19
+ @references_count = 0
19
20
  end
20
-
21
-
21
+
22
+
22
23
  def new_attribute column, one_to_one
23
-
24
+
24
25
  attribute = Attribute.new column
25
26
  @attributes << attribute
26
-
27
- @references += 1 if attribute.reference?
28
-
29
- if attribute.required? && attribute.name != 'position' && !attribute.boolean?
30
- if one_to_one then @required_one_to_ones << attribute.name
31
- else @requireds << attribute.name
27
+
28
+ @references_count += 1 if attribute.reference?
29
+
30
+ if attribute.validate_presence?
31
+ if one_to_one then @presence_validated_one_to_ones << attribute
32
+ else @presence_validateds << attribute
32
33
  end
33
34
  end
34
-
35
+
35
36
  if attribute.attachment?
36
- @attachments << attribute.attachment_name
37
- @required_attachments << attribute.attachment_name if attribute.required_attachment?
37
+ @attachments << attribute
38
+ @required_attachments << attribute if attribute.required_attachment?
38
39
  end
39
-
40
+
40
41
  if attribute.max_number
41
42
  @max_numbers[attribute.max_number] ||= []
42
43
  @max_numbers[attribute.max_number] << attribute.name
43
44
  end
44
-
45
+
45
46
  if attribute.max_length
46
47
  @max_lengths[attribute.max_length] ||= []
47
48
  @max_lengths[attribute.max_length] << attribute.name
48
49
  end
49
50
 
51
+ accessible_name = attribute.accessible_name
52
+ @accessibles << accessible_name if accessible_name.present?
53
+
50
54
  attribute
51
55
  end
52
-
56
+
53
57
  def each
54
58
  @attributes.each { |a| yield a }
55
59
  end
56
-
60
+
57
61
  def join?
58
- @references == @attributes.select{ |a| a.name != 'position' }.count && @references == 2
62
+ @references_count == @attributes.select{ |a| a.name != 'position' }.count && @references_count == 2
59
63
  end
60
-
64
+
61
65
  def validations?
62
66
  validations.any?
63
67
  end
64
-
65
- def attr_protecteds?
66
- attr_protecteds.present?
68
+
69
+ def attr_accessors?
70
+ attr_accessors.present?
67
71
  end
68
-
69
- def acts_as_markdowns?
70
- acts_as_markdowns.present?
72
+
73
+ def attr_accessibles?
74
+ attr_accessibles.present?
71
75
  end
72
-
76
+
73
77
  def attachments?
74
78
  @attachments.any?
75
79
  end
76
-
80
+
77
81
  def validations
78
82
  @validations ||= get_validations
79
83
  end
80
-
81
- def acts_as_markdowns
82
- @acts_as_markdowns ||= (names = @attributes.select(&:text?).map(&:name)).any? ? "acts_as_markdown #{join_names(names)}" : ''
83
- end
84
-
84
+
85
85
  def to_s_string
86
86
  case
87
87
  when name? then 'name'
@@ -89,116 +89,117 @@ module Schofield
89
89
  when text? then 'text'
90
90
  end
91
91
  end
92
-
92
+
93
93
  def attached_files
94
- @attachments.map { |attachment_name|
95
- string = "\n has_attached_file :#{attachment_name}, "
96
- indentation = ' ' * (string.length - 1)
97
- string += ":path => ':class/:id.:extension',\n"
98
- string += indentation + ":storage => :s3,\n"
99
- string += indentation + ":s3_credentials => \"\#{Rails.root}/config/s3.yml\",\n"
100
- string += indentation + ":url => ':s3_domain_url'"
101
- }.join("\n")
94
+ @attachments.map { |attribute|
95
+ "\n has_attached_file :#{attribute.attachment_name}, {" + (attribute.image? ? image_attachment(name) : non_image_attachment(name)) + "\n }.merge(S3_ATTACHMENT_INFO)"
96
+ }.join("\n")
102
97
  end
103
-
104
-
105
-
106
- private
107
-
108
- def attr_protecteds
109
- @attr_protecteds ||= (@attachments.any? ? 'attr_protected :' + @attachments.map { |attachment_name|
110
- self.select { |attribute|
111
- (match_data = attribute.name.match(/^#{attachment_name}_(.+)$/)).present? && %w(file_name content_type file_size updated_at).include?(match_data[1])
112
- }.map(&:name)
98
+
99
+ def attr_accessors
100
+ @attr_accessors ||= (@attachments.any? ? 'attr_accessor :' + @attachments.map { |attribute|
101
+ %w( _content_type _file_size ).map{ |suffix| "#{attribute.attachment_name}#{suffix}" } + (attribute.image? ? ["#{attribute.attachment_name}_dimensions"] : [])
113
102
  }.flatten.join(', :') : '')
114
103
  end
115
-
116
- def names_matching regex
117
- self.select { |a| a.name.match(regex) }.map(&:name)
118
- end
119
-
120
- def join_names names
121
- ":#{names.join(', :')}"
122
- end
123
-
124
- def get_validations
125
- @validations = []
126
- validate_presence
127
- validate_presence_unless_nested
128
- validate_length
129
- validate_numericality
130
- validate_email_address
131
- validate_phone_number
132
- validate_url
133
- validate_boolean
134
- validate_attachment_presence
135
- @validations
104
+
105
+ def attr_accessibles
106
+ @attr_accessibles ||= @accessibles.any? ? 'attr_accessible :' + @accessibles.join(', :') : ''
136
107
  end
137
-
138
- def validate_presence
139
- if (names = @requireds.map { |a| a.gsub(/_id$/, '') }).any?
140
- @validations << "validates #{join_names(names)}, :presence => true"
108
+
109
+
110
+
111
+ private
112
+
113
+ def names_matching regex
114
+ self.select { |a| a.name.match(regex) }.map(&:name)
141
115
  end
142
- end
143
-
144
- def validate_boolean
145
- if (booleans = select { |a| a.boolean? && a.required? }).any?
146
- @validations << "validates #{join_names(booleans.map(&:name))}, :boolean => true"
116
+
117
+ def join_names names
118
+ ":#{names.join(', :')}"
147
119
  end
148
- if (booleans = select { |a| a.boolean? && !a.required? }).any?
149
- @validations << "validates #{join_names(booleans.map(&:name))}, :boolean => true, :allow_nil => true"
120
+
121
+ def get_validations
122
+ @validations = []
123
+ validate_presence
124
+ validate_presence_unless_nested
125
+ validate_length
126
+ validate_numericality
127
+ validate_email_address
128
+ validate_phone_number
129
+ validate_url
130
+ validate_attachments
131
+ @validations
150
132
  end
151
- end
152
-
153
- def validate_presence_unless_nested
154
- if (names = @required_one_to_ones.map { |a| a.gsub(/_id$/, '') }).any?
155
- @validations << "validates #{join_names(names)}, :presence => true, :unless => :nested"
133
+
134
+ def validate_presence
135
+ if (names = @presence_validateds.map(&:actual_name)).any?
136
+ @validations << "validates #{join_names(names)}, :presence => true"
137
+ end
156
138
  end
157
- end
158
139
 
159
- def validate_length
160
- @max_lengths.each do |length, names|
161
- @validations << "validates #{join_names(names)}, :length => { :maximum => #{length} }, :allow_nil => true"
140
+ def validate_presence_unless_nested
141
+ if (names = @presence_validated_one_to_ones.map(&:actual_name)).any?
142
+ @validations << "validates #{join_names(names)}, :presence => true, :unless => :nested"
143
+ end
162
144
  end
163
- end
164
145
 
165
- def validate_numericality
166
- @max_numbers.each do |number, names|
167
- @validations << "validates #{join_names(names)}, :numericality => { :less_than_or_equal_to => #{number} }, :allow_nil => true"
146
+ def validate_length
147
+ @max_lengths.each do |length, names|
148
+ @validations << "validates #{join_names(names)}, :length => { :maximum => #{length} }, :allow_nil => true"
149
+ end
168
150
  end
169
- end
170
151
 
171
- def validate_email_address
172
- if (names = names_matching(/email_address$/)).any?
173
- @validations << "validates #{join_names(names)}, :email => true, :allow_nil => true"
152
+ def validate_numericality
153
+ @max_numbers.each do |number, names|
154
+ @validations << "validates #{join_names(names)}, :numericality => { :less_than_or_equal_to => #{number} }, :allow_nil => true"
155
+ end
156
+ end
157
+
158
+ def validate_email_address
159
+ if (names = names_matching(/email_address$/)).any?
160
+ @validations << "validates #{join_names(names)}, :email => true, :allow_nil => true"
161
+ end
174
162
  end
175
- end
176
163
 
177
- def validate_phone_number
178
- if (names = names_matching(/phone_number$/)).any?
179
- @validations << "validates #{join_names(names)}, :phone_number => true, :allow_nil => true"
164
+ def validate_phone_number
165
+ if (names = names_matching(/phone_number$/)).any?
166
+ @validations << "validates #{join_names(names)}, :phone_number => true, :allow_nil => true"
167
+ end
180
168
  end
181
- end
182
169
 
183
- def validate_url
184
- if (names = names_matching(/url$/)).any?
185
- @validations << "validates #{join_names(names)}, :url => true, :allow_nil => true"
170
+ def validate_url
171
+ if (names = names_matching(/url$/)).any?
172
+ @validations << "validates #{join_names(names)}, :url => true, :allow_nil => true"
173
+ end
186
174
  end
187
- end
188
175
 
189
- def validate_attachment_presence
190
- @validations << "validates_attachment_presence #{join_names(@required_attachments)}" if @required_attachments.any?
191
- end
192
-
193
- private
176
+ def validate_attachments
177
+ @attachments.each do |attribute|
178
+ name = attribute.attachment_name
179
+ @validations << "validates_attachment_presence :#{name}" if attribute.required_attachment?
180
+ @validations << "validates_attachment_content_type :#{name}, Rails.configuration.bodmin.image_content_type" if attribute.image?
181
+ @validations << "validates_attachment_size :#{name}, :less_than => 10.megabytes"
182
+ @validations << "validates_attachment_dimensions :#{name}, :width => 1..Infinity, :height => 1..Infinity" if attribute.image?
183
+ end
184
+ end
185
+
186
+ def image_attachment name
187
+ "\n :styles => { :admin => '96x78#' }," +
188
+ "\n :path => 'images/:class_with_thumbnails/:id/:fingerprint.:extension'," +
189
+ "\n :convert_options => { :admin => \"-colorspace RGB -strip \#{Rails.configuration.bodmin.image_quality}\" }"
190
+ end
191
+
192
+ def non_image_attachment name
193
+ "\n :path => 'downloads/:class/:id/:fingerprint.:extension'"
194
+ end
194
195
 
195
196
  def method_missing(method, *args, &block)
196
197
  if match_data = method.to_s.match(/^(.+)\?$/)
197
198
  self.find { |a| a.name == match_data[1] }.present?
198
199
  end
199
200
  end
200
-
201
+
201
202
  end
202
-
203
+
203
204
  end
204
205
  end