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_initialize_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 initialized with no values and it is not saved

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 in the database or a new form subject instance



254
255
256
257
258
259
260
261
262
263
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 254

def find_or_initialize_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()
  end
  return form_subject
end

#find_or_initialize_multipart_in_progress_form(form_name, form_subject) ⇒ Object

Returns the InProgressForm object when given the form name and subject

Initializes but does not asve 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



272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 272

def find_or_initialize_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 the form subject is a new_record, in_progress_form should be nil
  # trying to stop weird edge cases from killing me (JH 5-15-2012)
  if form_subject.new_record? || !in_progress_form
    in_progress_form = MultipartForm::InProgressForm.new(
      :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)


241
242
243
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 241

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



328
329
330
331
332
333
334
335
336
337
338
339
340
341
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 328

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



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 211

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



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 189

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)


232
233
234
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 232

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



97
98
99
100
101
102
103
104
105
106
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 97

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_initialize_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



179
180
181
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 179

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



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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 113

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

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

  in_progress_form = find_or_initialize_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] && params[:commit] != self.stay_string )
        completed = redirect_to_next_multipart_form_part(form_name, @form_subject, part)

        # if the form has been completed, set last_completed step to the first part of the form (JH 5-24-2012)
        # the next time the user edits the form, they will go to the first page
        # they should not be automatically redirected to the show page
        saved_step = ( completed ? "none" : part )

        # added form_subject_id in case it was not set when the in_progress_form was created (JH 5-15-2012)
        # this would happen on a new page, but not an edit page
        in_progress_form.update_attributes({
          :form_subject_id => @form_subject.id, 
          :last_completed_step => saved_step,
          :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



302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
# File 'lib/acts_as_multipart_form/multipart_form_in_controller.rb', line 302

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