polygallery 0.2.5 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 498466889ad29ec6561646661ebb6034617ccfd8
4
- data.tar.gz: 35afdcbab075aae765308ce535853bff92f708c4
3
+ metadata.gz: c2220d771dc5f8a3fd23774aa1634b548b19cf7f
4
+ data.tar.gz: 59130d77b7a9a7911128fab5b9a43cd0a170b744
5
5
  SHA512:
6
- metadata.gz: ff943059206c15033fda40513179917e33b5c60a2bb25442792f93a581576248bc8b271d0f693279c28f180f2e9b05fee8bb98cb02dd4561a7c8dabc3aac72ea
7
- data.tar.gz: 858c812e8c2103186deac49fe8165f9d552a0d0d7c74e4c3805e74bb83b73cec678f2e041c66ec833a4c828e45d6c9f72e4a3ba1c2e2352de5e8da9536085623
6
+ metadata.gz: e0fca5ba2a6d89cd400816b01d69e27ce2b8511934094c2a1288051b9d02aa80b0b37329825bef633e5fd41c1c1bd9e88fe9d75d40e8317b29a463feefef8e34
7
+ data.tar.gz: eec43e1ed442f0790aa38e306797eef002dcba0b454b0accdeda9901bf453c8af681c068d6aa01769bbac7a31e9da09c66d34a559f5860161f8d2d6225ca54cb
@@ -6,8 +6,10 @@ module Polygallery::StrongParams
6
6
 
7
7
  def polygallery_params(association='photos')
8
8
  [:id, :title, :galleryable_id, :galleryable_type,
9
- :_destroy, {:"#{association}_attributes" =>
10
- [:id, :photo, :title, :caption, :gallery_title,
11
- :galleryable_id, :galleryable_type, :_destroy]}]
9
+ :_destroy, {:photos_attributes => polyphoto_params(association) } ]
10
+ end
11
+ def polyphoto_params(association='photos')
12
+ [:id, :photo, :title, :caption, :gallery_title,
13
+ :galleryable_id, :galleryable_type, :_destroy]
12
14
  end
13
15
  end
@@ -38,6 +38,10 @@ module Polygallery
38
38
  validates_attachment_presence(:photo) if validations[:presence]
39
39
 
40
40
  before_validation :process_photo_to_upload
41
+ # TODO: figure out why save gets called so much!
42
+ # before_save {
43
+ # # puts "Photo changes: #{self.changes.inspect}"
44
+ # puts 'SAVING PHOTO!' }
41
45
  end
42
46
 
43
47
  def init_associations(settings=HasPolygallery::DEFAULTS)
@@ -6,7 +6,7 @@
6
6
 
7
7
  - if options[:label]
8
8
  %h3.lead
9
- = link_to_add_association 'Add Photo', ff, photo_association_name, :partial => 'polygallery/photos/simple_fields_for', :class => 'btn btn-default btn-sm pull-right', :data => {:association_insertion_node => "##{photo_association_name} .photo-receptacle", :association_insertion_method => 'append'}
9
+ = link_to_add_association 'Add Photo', ff, :photos, :partial => 'polygallery/photos/simple_fields_for', :class => 'btn btn-default btn-sm pull-right', :data => {:association_insertion_node => "##{photo_association_name} .photo-receptacle", :association_insertion_method => 'append'}
10
10
  - if options[:label] == true
11
11
  = gallery.title.titleize
12
12
  - else
@@ -19,10 +19,5 @@
19
19
  %th File
20
20
  %th.text-center Actions
21
21
  %tbody.photo-receptacle
22
- = ff.simple_fields_for photo_association_name do |pf|
22
+ = ff.simple_fields_for :photos do |pf| # photo_association_name do |pf|
23
23
  = render 'polygallery/photos/simple_fields_for', :f => pf
24
-
25
- -#- if !options[:label]
26
- -# = ff.input_field :content, options[:input_html].merge({:as => :ckeditor})
27
- -#- else
28
- -#= ff.input :content, :as => :ckeditor, :label => options[:label].is_a?(String) ? options[:label] : name.to_s.titleize, :input_html => name.is_a?(String) ? options[:input_html].merge({:value => pb.content}) : options[:input_html]
@@ -3,7 +3,7 @@
3
3
  = f.input_field :gallery_title, :as => :hidden
4
4
  = f.input_field :galleryable_id, :as => :hidden
5
5
  = f.input_field :galleryable_type, :as => :hidden
6
- = image_tag f.object.photo.file? ? f.object.photo.url(:thumb) : 'polygallery/thumbnail-missing.jpg', :class => 'img-responsive' # image_path('polygallery/thumbnail-missing.jpg')
6
+ = image_tag f.object.photo.file? ? f.object.photo.url(:thumb) : 'polygallery/thumbnail-missing.jpg', class: 'img-responsive'
7
7
  %td
8
8
  = f.input_field :photo
9
9
  = f.input_field :caption, :placeholder => "Caption... (optional)", :style => "margin-top:5px;", :as => :string
@@ -0,0 +1,22 @@
1
+ require 'polygallery/factories'
2
+ module Polygallery
3
+ module CapybaraHelpers
4
+ def add_photo_to_form(attrs=nil, table_id='photos')
5
+ attrs ||= build :polygallery_photo
6
+ tr_selector = ".polygallery-cocoon-table##{table_id} tr"
7
+ last_tr = all(tr_selector).last
8
+ if last_tr.find('input[id$="_photo"]').value.present?
9
+ page.execute_script <<-SCRIPT
10
+ $('.btn.add_fields[data-association-insertion-node="##{table_id} .photo-receptacle"]').click();
11
+ SCRIPT
12
+ last_tr = all(tr_selector).last
13
+ end
14
+ within last_tr do
15
+ random_photo = get_random_photo
16
+ find('input[id$="_photo"]').set random_photo
17
+ find('input[id$="_caption"]').set(attrs.caption)
18
+ yield if block_given?
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,9 @@
1
+ MFaker = defined?(Faker) ? Faker : FFaker
2
+
3
+ require 'polygallery/factories/polygallery/galleries'
4
+ require 'polygallery/factories/polygallery/photos'
5
+
6
+ def get_random_photo
7
+ photos_dir = Rails.root.join 'spec', 'upload_files'
8
+ Dir.glob(photos_dir.join('*.{jpg,png,gif}')).sample
9
+ end
@@ -1,13 +1,20 @@
1
- MFaker = defined?(Faker) ? Faker : FFaker
2
-
3
1
  FactoryGirl.define do
2
+ # to_create do |instance|
3
+ # raise "Save failed for #{instance.class} (#{instance.errors.full_messages.inspect})" if !instance.save
4
+ # end
5
+
4
6
  factory :polygallery_gallery, :class => Polygallery::Gallery do
7
+ title 'gallery'
5
8
 
9
+ trait :with_photo do
10
+ photos_attributes { generate_photo_attributes } end
6
11
  trait :with_photos do
7
- after(:create) do |gallery|
8
- create :polygallery_photo, :gallery => gallery
9
- end
10
- end
11
-
12
+ photos_attributes { generate_photo_attributes 3 } end
13
+ trait :with_tons_of_photos do
14
+ photos_attributes { generate_photo_attributes 10 } end
12
15
  end
13
16
  end
17
+ def generate_photo_attributes(count=1, attrs={})
18
+ if count.is_a? Hash; attrs = count; count = 1 end
19
+ (1..count).map{ attributes_for :polygallery_photo, attrs }
20
+ end
@@ -1,8 +1,12 @@
1
1
  include ActionDispatch::TestProcess
2
- MFaker = defined?(Faker) ? Faker : FFaker
3
2
 
4
3
  FactoryGirl.define do
4
+ # to_create do |instance|
5
+ # raise "Save failed for #{instance.class} (#{instance.errors.full_messages.inspect})" if !instance.save
6
+ # end
7
+
5
8
  factory :polygallery_photo, :class => Polygallery::Photo do
6
9
  caption { [nil, MFaker::BaconIpsum.paragraph].sample }
10
+ photo { File.new get_random_photo }
7
11
  end
8
12
  end
@@ -23,8 +23,9 @@ module Polygallery
23
23
  :nested_attributes => {
24
24
  :gallery => { :reject_if => :all_blank },
25
25
  :photos => {
26
- :reject_if => proc {|attributes| !attributes.key?('id') && attributes['photo'].nil? },
27
- :allow_destroy => true }
26
+ :allow_destroy => true,
27
+ :reject_if => proc {|attributes|
28
+ !attributes.key?('id') && attributes['photo'].nil? } }
28
29
  },
29
30
  :validates => {},
30
31
  :paperclip => {
@@ -47,9 +48,6 @@ module Polygallery
47
48
  title = 'gallery'
48
49
  end
49
50
 
50
- # associations = options[:associations]
51
- # gallery_association = options[:associations][:gallery] if associations.present?
52
- # gallery_class_name = gallery_association[:class_name] if gallery_association.present?
53
51
  defaults = HasPolygallery::DEFAULTS
54
52
  if options[:association_names].nil? && title.to_s != 'gallery'
55
53
  options[:association_names] = {
@@ -60,18 +58,35 @@ module Polygallery
60
58
  settings = defaults.deep_merge(options)
61
59
  cattr_accessor "#{title}_settings".to_sym
62
60
  send("#{title}_settings=".to_sym, settings)
61
+ attr_accessor :"#{title}_attributes", :galleries_built
63
62
 
64
63
  has_one title.to_sym, -> { where(:title => title.to_s) }, settings[:associations][:gallery]
65
64
  has_many settings[:association_names][:photos],
66
65
  :through => :"#{title}",
67
- :source => settings[:association_names][:photos],
66
+ :source => :photos, # settings[:association_names][:photos],
68
67
  :class_name => settings[:associations][:photos][:class_name]
69
68
  accepts_nested_attributes_for settings[:association_names][:gallery],
70
69
  settings[:nested_attributes][:gallery]
71
70
  accepts_nested_attributes_for settings[:association_names][:photos],
72
71
  settings[:nested_attributes][:photos]
73
72
 
74
- after_initialize :build_galleries
73
+ after_initialize :if => :new_record? do
74
+ # puts "GA: #{self.gallery_attributes.inspect}"
75
+ if self.gallery_attributes.nil?
76
+ # puts 'BUILDING FIRST PHOTOS ON INIT!'
77
+ build_first_photos
78
+ # build_gallery_associations
79
+ end
80
+ end
81
+ # puts instance.inspect
82
+ # instance.new_record? && !instance.has_polygallery? }
83
+ before_validation do # , :on => :update # , :unless => :new_record?
84
+ # puts 'BUILDING GALLERIES ON VALIDATION'
85
+ # unless self.galleries_built?
86
+ build_gallery_associations
87
+ # end
88
+ prune_empty_photos
89
+ end
75
90
  before_save :ensure_galleryable_set
76
91
 
77
92
  include HasPolygallery::LocalInstanceMethods
@@ -87,19 +102,20 @@ module Polygallery
87
102
  polygalleries.include?(gallery_title)
88
103
  end
89
104
 
90
- # def new(*args)
91
- # super(*args)
92
- # end
93
-
94
105
  end
95
106
 
96
107
  module LocalInstanceMethods
97
108
  def polygalleries
98
- # TODO: use association reflections instead of direct class selection
99
- Gallery.select('polygallery_galleries.title')
100
- .where(:galleryable => self)
101
- .group('polygallery_galleries.title')
102
- .map(&:title)
109
+ self.class.polygalleries.each do |pg_name|
110
+ gallery_opts = self.send(:"#{pg_name}_settings")
111
+ gallery_classname = gallery_opts[:associations][:gallery][:class_name]
112
+ gallery_class = Object.const_get gallery_classname
113
+ table_name = gallery_class.table_name
114
+ gallery_class.select("#{table_name}.title")
115
+ .where(:galleryable => self)
116
+ .group("#{table_name}.title")
117
+ .map(&:title)
118
+ end
103
119
  end
104
120
 
105
121
  def has_polygallery?(gallery_title=nil)
@@ -107,32 +123,72 @@ module Polygallery
107
123
  polygalleries.include?(gallery_title)
108
124
  end
109
125
 
110
- def build_galleries
111
- return unless self.class.has_polygallery?
112
- self.class.polygalleries.each do |pg|
113
- gallery_association = send pg
114
- next if gallery_association.present?
115
- gallery_settings = self.send :"#{pg.to_s}_settings"
116
- if gallery_association.nil?
117
- built_gallery = send :"build_#{pg.to_s}",
118
- :polygallery_options => gallery_settings
119
- gallery_association = send :"#{pg.to_s}=", built_gallery
126
+ def build_gallery_associations
127
+ return [] unless self.class.has_polygallery?
128
+ # puts 'BUILDING GALLERIES!'
129
+ gallery_associations = self.class.polygalleries.map{|pg|
130
+ self.build_gallery_association pg }
131
+ self.galleries_built = true
132
+ gallery_associations
133
+ end
134
+ def build_gallery_association(gallery_name=:gallery)
135
+ gallery_association = send gallery_name
136
+ attrs_for_this_gallery = send(:"#{gallery_name}_attributes") || {}
137
+ if gallery_association.present?
138
+ # if attrs_for_this_gallery.empty?
139
+ # gallery_association.photos.each do |p|
140
+ # if p.photo_to_upload.present?
141
+ # p.photo = File.new p.photo_to_upload
142
+ # p.photo_to_upload = nil
143
+ # end
144
+ # relevant_changes = p.changed -
145
+ # %w(galleryable_type galleryable_id gallery_title)
146
+ # if relevant_changes.any?
147
+ # attrs_for_this_photo = Hash[*relevant_changes.map{|column|
148
+ # [ column, p.send(column) ] }.flatten]
149
+ # attrs_for_this_gallery[:photos_attributes] ||= {}
150
+ # attrs_for_this_gallery[:photos_attributes][(p.id ||
151
+ # attrs_for_this_gallery[:photos_attributes].length).to_s] = attrs_for_this_photo
152
+ # end
153
+ # end
154
+ # # return gallery_association
155
+ # end
156
+ if attrs_for_this_gallery.empty?
157
+ # puts 'Returning due to empty attrs!'
158
+ return gallery_association
159
+ end
160
+ if gallery_association.persisted?
161
+ # puts 'Updating an existing gallery!'
162
+ gallery_association.update_attributes attrs_for_this_gallery
163
+ else
164
+ attrs_for_this_gallery.each{|k, v|
165
+ gallery_association.send :"#{k}=", v }
120
166
  end
121
- gallery_association.galleryable ||= self
167
+ return gallery_association
122
168
  end
169
+ settings_for_this_gallery = send :"#{gallery_name}_settings"
170
+ attrs_for_this_gallery[:polygallery_options] = settings_for_this_gallery
171
+ # puts "Building a new gallery: #{gallery_name}"
172
+ built_gallery = send :"build_#{gallery_name}", attrs_for_this_gallery
173
+ gallery_association = send :"#{gallery_name}=", built_gallery
174
+ gallery_association.galleryable ||= self
175
+ gallery_association
123
176
  end
124
177
 
125
178
  def build_first_photos
126
179
  return unless self.class.has_polygallery?
127
- self.class.polygalleries.each {|pg| send(pg).build_first_photo }
180
+ # self.class.polygalleries.each{|pg|
181
+ # build_gallery_association pg
182
+ # send(pg.to_sym).build_first_photo }
183
+ build_gallery_associations.map(&:build_first_photo)
128
184
  end
129
185
 
130
186
  def first_photo
131
187
  return unless self.class.has_polygallery?
132
188
  first_p = nil
133
189
  self.class.polygalleries.each do |pg|
134
- gallery_settings = send :"#{pg.to_s}_settings"
135
- ptos = send(gallery_settings[:association_names][:photos])
190
+ settings_for_this_gallery = send :"#{pg.to_s}_settings"
191
+ ptos = send(settings_for_this_gallery[:association_names][:photos])
136
192
  .select{|p| p.photo.file? }
137
193
  next if ptos.empty?
138
194
  first_p = ptos.first.photo
@@ -142,15 +198,19 @@ module Polygallery
142
198
  end
143
199
 
144
200
  def ensure_galleryable_set
145
- self.class.polygalleries.each do |pg|
146
- gallery_association = self.send :"#{pg}"
147
- gallery_association.galleryable ||= self
148
- gallery_association.polygallery_photos.each do |pp|
149
- pp.galleryable ||= self
150
- end
201
+ gallery_associations.each do |ga|
202
+ ga.galleryable ||= self
203
+ ga.polygallery_photos.each{|pp|
204
+ pp.galleryable ||= self }
151
205
  end
152
206
  end
153
207
 
208
+ def gallery_associations
209
+ self.class.polygalleries.map{|pg| send(pg) } end
210
+ def galleries_built?; self.galleries_built.present? end
211
+ def prune_empty_photos
212
+ gallery_associations.each(&:prune_empty_photos) end
213
+
154
214
  end
155
215
  end
156
216
  end
@@ -17,6 +17,7 @@ module Polygallery
17
17
  options = title
18
18
  title = association_names[:photos].to_s
19
19
  end
20
+ attr_accessor :photos_attributes, :photos_built
20
21
 
21
22
  settings = defaults.deep_merge options
22
23
  init_associations settings
@@ -24,7 +25,12 @@ module Polygallery
24
25
  after_initialize do
25
26
  self.polygallery_options ||= self.polygallery_settings
26
27
  self.initialize_polygallery
28
+ # self.build_polygallery_photos # if new_record? && !polygallery_photos_attributes.is_a?(Hash)
27
29
  end
30
+ after_initialize :build_polygallery_photos, :if => :new_record?
31
+ before_validation :set_nested_attributes_to_correct_gallery
32
+ before_validation :build_polygallery_photos, :unless => :photos_built? # , :on => :update
33
+ before_validation :prune_empty_photos
28
34
 
29
35
  include HasPolyphotos::LocalInstanceMethods
30
36
  end
@@ -36,9 +42,11 @@ module Polygallery
36
42
  def init_associations(settings=HasPolygallery::DEFAULTS)
37
43
  belongs_to :galleryable, :polymorphic => true
38
44
  photos_name = settings[:association_names][:photos]
39
- has_many photos_name, settings[:associations][:photos]
40
- accepts_nested_attributes_for photos_name,
41
- settings[:nested_attributes][:photos]
45
+ has_many :photos, settings[:associations][:photos].symbolize_keys
46
+ # has_many photos_name, settings[:associations][:photos].symbolize_keys
47
+ accepts_nested_attributes_for :photos,
48
+ settings[:nested_attributes][:photos].symbolize_keys
49
+ attr_accessor :"#{photos_name.to_s}_attributes"
42
50
  end
43
51
 
44
52
  end
@@ -82,8 +90,79 @@ module Polygallery
82
90
  self.class.polygallery_settings
83
91
  end
84
92
 
85
- def polygallery_photos
86
- self.send self.polygallery_settings[:association_names][:photos]
93
+ def polygallery_photos_name
94
+ self.polygallery_settings[:association_names][:photos] end
95
+ def polygallery_photos; photos end # send self.polygallery_photos_name end
96
+ def polygallery_photos_attributes; self.photos_attributes end
97
+ # self.send :"#{polygallery_photos_name.to_s}_attributes" end
98
+ def polygallery_photos_attributes=(v); self.photos_attributes = v end
99
+ # self.send :"#{polygallery_photos_name.to_s}_attributes=", v end
100
+ def polygallery_photos_classname
101
+ self.polygallery_settings[:associations][:photos][:class_name] end
102
+ def polygallery_photos_class
103
+ Object.const_get polygallery_photos_classname end
104
+
105
+ def set_nested_attributes_to_correct_gallery
106
+ # if self.photos_attributes.present? &&
107
+ # self.polygallery_photos_name.to_s != 'photos'
108
+ # self.send :"#{polygallery_photos_name.to_s}_attributes=", self.photos_attributes
109
+ # self.photos_attributes = nil
110
+ # end
111
+ end
112
+
113
+ def build_polygallery_photos
114
+ # puts "BUILDING PHOTOS for #{title}"
115
+ # puts "PHOTO ATTRS: #{self.photos_attributes.inspect}"
116
+ # Convert attributes to array if in hash form
117
+ # self.photos_attributes =
118
+ # self.photos_attributes.map{|_, v| v
119
+ # } if self.photos_attributes.is_a? Hash
120
+
121
+ # Initialize a duplicate
122
+ attrs_for_photos = if self.photos_attributes.is_a? Hash
123
+ self.photos_attributes.values
124
+ else
125
+ ( self.photos_attributes || [] ).dup
126
+ end
127
+ return unless attrs_for_photos.any?
128
+ return if self.photos_built?
129
+
130
+ attrs_for_photos.each_with_index do |attrs_for_photo, index|
131
+ attrs_for_photo[:polygallery_options] = self.polygallery_settings
132
+ should_destroy = attrs_for_photo.delete(:_destroy) == 'true'
133
+ if attrs_for_photo.key? :id
134
+ existing_id = attrs_for_photo.delete(:id).to_i
135
+ existing_photo = self.polygallery_photos_class.find existing_id
136
+ if should_destroy
137
+ # puts 'Destroying a photo'
138
+ existing_photo.destroy
139
+ else
140
+ # puts 'Updating an existing photo'
141
+ existing_photo.update_attributes attrs_for_photo end
142
+ # elsif attrs_for_photo.key? :built
143
+ # puts 'Photo already built'
144
+ else
145
+ # puts 'Building a new photo'
146
+ # puts attrs_for_photo.inspect
147
+ # raise 'WOO' if self.polygallery_photos
148
+ built_photo = self.polygallery_photos.build attrs_for_photo
149
+ set_nest built_photo
150
+ # self.polygallery_photos_attributes[index][:built] = true
151
+ end
152
+ end
153
+ self.photos_built = true
154
+ end
155
+
156
+ def photos_built?; self.photos_built.present? end
157
+
158
+ def prune_empty_photos
159
+ # puts "#{title} is pruning empty photos..."
160
+ polygallery_photos.each {|pp|
161
+ if pp.new_record? && !pp.photo.file?
162
+ # TODO: find a way not to generate these photos in the first place!
163
+ # puts 'Marking photo for destruction'
164
+ pp.mark_for_destruction
165
+ end }
87
166
  end
88
167
 
89
168
  end
@@ -1,3 +1,3 @@
1
1
  module Polygallery
2
- VERSION = "0.2.5"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: polygallery
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - MacKinley Smith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-24 00:00:00.000000000 Z
11
+ date: 2015-08-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -305,7 +305,9 @@ files:
305
305
  - lib/generators/polygallery/install/templates/add_gallery_title.rb
306
306
  - lib/generators/polygallery/install/templates/polygallery_migration.rb
307
307
  - lib/polygallery.rb
308
+ - lib/polygallery/capybara_helpers.rb
308
309
  - lib/polygallery/engine.rb
310
+ - lib/polygallery/factories.rb
309
311
  - lib/polygallery/factories/polygallery/galleries.rb
310
312
  - lib/polygallery/factories/polygallery/photos.rb
311
313
  - lib/polygallery/glue.rb