Skip to content

Instantly share code, notes, and snippets.

@sheamf
Last active February 24, 2016 16:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sheamf/d4133a585fab42a84440 to your computer and use it in GitHub Desktop.
Save sheamf/d4133a585fab42a84440 to your computer and use it in GitHub Desktop.
class CompanyForm
extend ActiveModel::Naming
include ActiveModel::Conversion
include ActiveModel::Validations
attr_reader :name, :employee_count
with_options presence: true do |required|
required.validates :name
required.validates :employee_count
end
def self.model_name
ActiveModel::Name.new(self, nil, "Company")
end
def valid?
validate_rows = @office_rows.all?(&:valid?)
validate_form = super()
validate_rows && validate_form
end
def submit(params)
extract_params(params)
if valid?
persist!
true
else
false
end
end
def extract_params(params)
@name = params[:name]
@employee_count = params[:employee_count]
@office_params = params[:office_rows]
end
class OfficeRow
attr_accessor :name, :city, :state, :employee_count
include ActiveModel::Validations
with_options presence: true do |required|
required.validates :name
required.validates :city
required.validates :state
required.validates :employee_count
end
def initialize(params = {})
@name = params[:name]
@city = params[:city]
@state = params[:state]
@employee_count = params[:employee_count]
end
def persisted?
false
end
end
class NewOfficeRow < OfficeRow
attr_accessor :company
def initialize(params = {})
@company = params[:company]
super
end
def persisted?
false
end
def persist! # find a better way to create the association
Office.create!(name: name, city: city, state: state, employee_count: employee_count, company_id: @company.try(:id))
end
end
end
class NewCompanyForm < CompanyForm
def persisted?
false
end
def office_rows
@office_rows ||= [NewOfficeRow.new] # uhhhh...
end
def persist!
@company = Company.new(name: name, employee_count: employee_count)
@office_rows.each do |office_row|
office = office_row.persist!
@company.offices << office
end
@company.save!
end
def extract_params(params)
super
@office_rows = @office_params.map do |k, office_attrs|
NewOfficeRow.new(office_attrs)
end
end
end
class EditCompanyForm < CompanyForm
attr_reader :company, :employee_count
def initialize(company)
@company = company
@name = company.name
@employee_count = company.employee_count
end
def office_rows
@office_rows ||= company.offices.map { |office| EditOfficeRow.new(office) }
end
def persisted?
true
end
def persist!
@office_rows.each { |office_row| office_row.persist! }
@company.update_attributes!(name: name, employee_count: employee_count)
end
def extract_params(params)
super
new_office_params = @office_params.select { |k, v| v[:id].blank? }
@office_rows = office_rows.select { |row| row.persisted? } # remove NewOfficeRow instances
@office_rows.each do |office_row|
params = @office_params.select { |k, v| v[:id] == office_row.office.id.to_s }
params = params.values.inject(:reduce)
office_row.extract_params(params)
end
new_office_params.each do |k, v|
params = v.merge(company: company)
@office_rows << NewOfficeRow.new(params)
end
end
class EditOfficeRow < OfficeRow
attr_reader :company, :office, :id
def initialize(office)
@office = office
@company = office.company
@id = office.id
@name = office.name
@city = office.city
@state = office.state
@employee_count = office.employee_count
end
def persisted?
true
end
def extract_params(params)
@remove = params[:remove]
@name = params[:name]
@city = params[:city]
@state = params[:state]
@employee_count = params[:employee_count]
end
def persist!
if flagged_for_deletion?
@office.destroy
else
@office.update_attributes!(name: name, city: city, state: state, employee_count: employee_count)
end
end
private
def flagged_for_deletion?
@remove == 'true'
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment