Module: ActsAsMultipartForm::MultipartFormInController::InstanceMethods

Defined in:
lib/acts_as_multipart_form/multipart_form_in_controller.rb

Instance Method Summary collapse

Instance Method Details

#find_or_create_multipart_form_subject(form_name, form_subject_id) ⇒ FormSubject

Given a form name and a form subject id, it creates the form subject The form subject is defined by the id and the multipart form’s model attribute

The subject is created with no values and saved without validations (this might change in the future) This is not a good situation but I don’t know how to ensure the form subject gets saved otherwise

Parameters:

  • form_name (Symbol)

    The name of the multipart form

  • form_dubject_id (Integer)

    The id of the form subject (could be nil)

Returns:

  • (FormSubject)

    The form subject object based on the multipart form’s model or nil if the id is set and not found



240
241
242
243
244
245
246
247
248
249
250
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 240

def find_or_create_multipart_form_subject(form_name, form_subject_id)
  # find or create the form subject
  model = self.multipart_forms[form_name][:model]
  if form_subject_id
    form_subject = model.constantize.find(form_subject_id)
  else
    form_subject = model.constantize.new()
    form_subject.save(:validate => false)
  end
  return form_subject
end

#find_or_create_multipart_in_progress_form(form_name, form_subject) ⇒ Object

Returns the InProgressForm object when given the form name and subject Creates the InPorgressForm object if it doesn’t exist for the given form name/form subject pair

Parameters:

  • form_name (Symbol)

    The name of the multipart form

  • form_subject (FormSubject)

    The multipart form’s subject



258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 258

def find_or_create_multipart_in_progress_form(form_name, form_subject)
  # find or create the in progress form
  # not sure why the polymorphic relationship isn't working here
  in_progress_form = MultipartForm::InProgressForm.where(
    :form_subject_id => form_subject.id, 
    :form_subject_type => form_subject.class.to_s, 
    :form_name => form_name.to_s).first
  if !in_progress_form
    in_progress_form = MultipartForm::InProgressForm.create(
      :form_subject_id => form_subject.id, 
      :form_subject_type => form_subject.class.to_s, 
      :form_name => form_name.to_s, 
      :last_completed_step => "none", 
      :completed => false)
  end
  return in_progress_form
end

#first_multipart_form_part?(form, part) ⇒ Boolean

Determines if the given multipart form part is the first part of the form

Parameters:

  • form (Symbol)

    The name of the multipart form

  • part (Symbol)

    The name o the current part

Returns:

  • (Boolean)


226
227
228
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 226

def first_multipart_form_part?(form, part)
  self.multipart_forms[form][:parts].first == part
end

#get_available_multipart_form_parts(form_name, last_completed_part) ⇒ Object

Gets the multipart form parts the user is allowed to directly link to with respect to the config information.

If the config option show_incomplete_parts is set to false, do not return parts past the in_progress_form’s last completed step

Parameters:

  • form_name (Symbol)

    The name of the form



311
312
313
314
315
316
317
318
319
320
321
322
323
324
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 311

def get_available_multipart_form_parts(form_name, last_completed_part)
  add_parts = true
  parts = []
  # loop over the parts
  self.multipart_forms[form_name][:parts].each do |part|
    if( add_parts && !part.match(/_update$/) )
      parts << { :name => part, :number => parts.length + 1 }
    end
    if !ActsAsMultipartForm.config.show_incomplete_parts && part.to_s == last_completed_part.to_s
      add_parts = false 
    end
  end
  return parts
end

#get_next_multipart_form_part(form, part, skip_update_part = false) ⇒ Object

Gets the next multipart form part for the form or returns the current part if it is first

Parameters:

  • form (Symbol)

    The name of the multipart form

  • part (Symbol)

    The name of the current part

  • skip_update_part (Boolean) (defaults to: false)

    If set to true, moves forward two parts instead of one



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 196

def get_next_multipart_form_part(form, part, skip_update_part = false)
  part_index = self.multipart_forms[form][:parts].index(part)

  if skip_update_part
    next_part_distance = 2
  else
    next_part_distance = 1
  end

  if part_index < self.multipart_forms[form][:parts].length - next_part_distance
    return self.multipart_forms[form][:parts][part_index + next_part_distance]
  else
    return part
  end
end

#get_previous_multipart_form_part(form, part, skip_update_part = false) ⇒ Object

Gets the previous multipart form part for the form or returns the current part if it is first

Parameters:

  • form (Symbol)

    The name of the multipart form

  • part (Symbol)

    The name of the current part

  • skip_update_part (Boolean) (defaults to: false)

    If set to true, moves back two parts instead of one



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 174

def get_previous_multipart_form_part(form, part, skip_update_part = false)
  part_index = self.multipart_forms[form][:parts].index(part)

  if skip_update_part
    prev_part_distance = 2
  else
    prev_part_distance = 1
  end

  if part_index - prev_part_distance >= 0
    return self.multipart_forms[form][:parts][part_index - prev_part_distance]
  else
    return self.multipart_forms[form][:parts].first
  end
end

#last_multipart_form_part?(form, part) ⇒ Boolean

Determines if the given multipart form part is the last part of the form

Parameters:

  • form (Symbol)

    The name of the multipart form

  • part (Symbol)

    The name o the current part

Returns:

  • (Boolean)


217
218
219
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 217

def last_multipart_form_part?(form, part)
  self.multipart_forms[form][:parts].last == part
end

A bad hack to load the multipart form information for the index page This must be called if you want to use the multipart_form/index_links partial

Adds several instance variables available for the view

Parameters:

  • form_name (Symbol)

    The name of the form

  • form_subjects (Array)

    An array of active record objects that are form subjects for the given form



93
94
95
96
97
98
99
100
101
102
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 93

def load_multipart_form_index_links(form_name, form_subjects)
  @multipart_form_index_parts = {}
  form_subjects.each do |form_subject|
    in_progress_form = find_or_create_multipart_in_progress_form(form_name, form_subject)
    @multipart_form_index_parts[form_subject.id] = {}
    @multipart_form_index_parts[form_subject.id][:parts] = get_available_multipart_form_parts(form_name, in_progress_form.last_completed_step)
    @multipart_form_index_parts[form_subject.id][:completed] = in_progress_form.completed
  end
  @multipart_form_path = (self.multipart_forms[form_name][:form_route] + "_path").to_sym
end

#multipart_form_action?(sym) ⇒ Boolean

Determines if the symbol matches a multipart form name

Parameters:

  • sym (Symbol)

    A name that may or may not correspond to a multipart form name

Returns:

  • (Boolean)

    Returns true if the symbol matches a multipart form name



164
165
166
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 164

def multipart_form_action?(sym)
  self.multipart_forms.keys.include?(sym)
end

#multipart_form_handlerObject

Handles multipart form setup on the controller Automatically called on the hire form action as a before filter

It adds a bunch of instance variables to the controller so they are accessible to the view page. Not sure if this is the best way to do things



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 109

def multipart_form_handler
  form_name = params[:action].to_sym
  form_subject_id = params[:id]

  @form_subject = find_or_create_multipart_form_subject(form_name, form_subject_id)
  params[:id] = @form_subject.id

  in_progress_form = find_or_create_multipart_in_progress_form(form_name, @form_subject)

  # set the part based on the params or in progress form
  if params[:multipart_form_part]
    part = params[:multipart_form_part].to_sym
  elsif in_progress_form.last_completed_step != "none"
    part = get_next_multipart_form_part(form_name, in_progress_form.last_completed_step.to_sym)
  else
    part = self.multipart_forms[form_name][:parts].first
  end

  # call and save the part information
  if(part && self.multipart_forms[form_name][:parts].include?(part.to_sym))
    result = self.send(part)
    
    if(part.match(/_update$/))
      if(result && result[:valid])
        completed = redirect_to_next_multipart_form_part(form_name, @form_subject, part)
        in_progress_form.update_attributes(:last_completed_step => part, :completed => completed)
      else
        # render the previous page but stay on this page so we keep the errors
        part = get_previous_multipart_form_part(form_name, part)
        # actually run the part we just found 
        # can't believe we missed this one (JH 3-20-2012)
        self.send(part)
      end
    end

    # move forward or backwards 2 parts for the previous and next links on the bredcrumb
    skip_update_part = true
    @breadcrumb_links= {
      :previous => get_previous_multipart_form_part(form_name, part, skip_update_part).to_s,
      :next => get_next_multipart_form_part(form_name, part, skip_update_part).to_s,
    }

    # needs to be a string so that the view can read it
    @next_multipart_form_part = get_next_multipart_form_part(form_name, part).to_s
    @multipart_form_part = part.to_s
    @available_multipart_form_parts = get_available_multipart_form_parts(form_name, in_progress_form.last_completed_step)
    @multipart_form_path = (self.multipart_forms[form_name][:form_route] + "_path").to_sym
    @multipart_form_complete = in_progress_form.completed
  end
end

#redirect_to_next_multipart_form_part(form_name, form_subject, part) ⇒ Object

Adds a redirect based on the information passed in. If on the last part of the form, tries to redirect to the view page, otherwise to the next form part.

This method needs signficantly more testing (7-20-2011)

Parameters:

  • form_name (Sybmol)

    The name of the form

  • form_subject (FormSubject)

    The subject of the form

  • part (Symbol)

    The current form part



285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 285

def redirect_to_next_multipart_form_part(form_name, form_subject, part)
  # set highest completed part to the current part4
  if(last_multipart_form_part?(form_name, part))
    # render the view page(not sure how to do this)
    redirect_to( send(self.multipart_forms[form_name][:show_route] + "_path", form_subject) )
    completed = true
  else
    # render the next page
    next_part = get_next_multipart_form_part(form_name, part)
    # maybe pass in a route
    redirect_to ( send(
      self.multipart_forms[form_name][:form_route] + "_path", 
      :id => form_subject.id.to_s, 
      :multipart_form_part => next_part.to_s))
    completed = false
  end
  return completed
end