This post by Jamis Buck about keeping Rails controllers skinny has always stuck with me. I have an app in which a zip file consisting of an XML file and some images is uploaded and used to create the model (mostly from the xml file, which points to the images).

Should all the code dealing with extracting the files from the zip and moving them to their appropriate place go in the controller or the model?



That article is pretty much classic. Yes, you should stick to the "fat models, skinny controllers, stupid views" architecture as long as the models make sense as objects (and they almost always do).

In your case, I'm not really sure what the output "model" should look like, but let's say it's a gallery. So you can create a model like this:

class Gallery # no "< ActiveRecord" if don't work with database

  attr_accessor :zip_file_path, :xml, :images

  def initialize(params ={})
    @zip_file_path = params[:zip_file_path]
    @xml = nil
    @images = []
    @output = nil # model: html code, path to file...

  def generate_model
    unzip_file! # populates @xml and @images
    transform_xml! # creates model into @output

  def unzip_file!

  def transform_xml!


It's just a rough design, you might want to make it more function-oriented (@xml, @images = unzip_file(@zip_file_path) ) etc.

Controller will then act just as a mediator between model and views/user:

class GalleriesController < ApplicationController
  def new()
    # display upload form for zip_file

 def create()
   # check input here, or leave it to model validations

  @output = Gallery.new(params).generate_model


Simple answer: Yes, as you already guess, this goes into the model.

Depending on how exactly the content of the zip look, you most likely hand it to a class method of the Image model, which then unpacks and evaluates the xml an creates the database records, downloads the images or whatever needs to be done.

In the controller you should have not much more than something like: (together with whatever authentication you need to handle of course)

Image.scan( params[:image_zip] )

An alternative way would be to write a class independently if the Image model to handle this task if you don't want to get too much code into this single model.

  • Thanks I like the idea of a util class working within the model to unpack things. – kreek Aug 17 '11 at 21:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.