cells

or "why using partials+helpers is batshit insane"

how we do it now

def render_file_uploader(purchased_items, purchased_order, opts={})
	#These are default options for file uplaoder
	options = {
			:product_element_selector => ".PurchasedItem",
			:upload_link_selector => ".FakeUploadLink img",
			:list_element_selector => ".Uploaded ul",
			:remove_link_selector => ".Remove img",
			:thumbnail_selector => ".Thumbnail img",
			:corrections_selector => ".UploadFileTable",
			:accept_runs_processing => false,
			:in_basket => false,
			:require_file_before_payment => false
	}
	unless purchased_order.nil?
		unless purchased_order.is_a? Hash
			order_options= {
							:documents_preflight_data => purchased_order.documents_preflight_data,
							:purchased_order_id => purchased_order.id,
							:use_advanced_approval => purchased_order.proof_kind == 'soft_proof',
							:production_order_status => (purchased_order.production_order ? purchased_order.production_order.status : false)
			}
			options.merge! order_options
		else
			options.merge! purchased_order
		end
	end
	options.merge! opts

	render_here :partial => "common/file_uploader_control", :locals => {:purchased_items => purchased_items, :options => options}
end
application_helper.rb

how we do it now

<script type="text/javascript">
	var webshop_file_uploader = new WebshopFileUploader(<%=  raw_json options.to_json %>);

	<% (purchased_items + purchased_items.map(&:parts)).flatten.each do |purchased_item| %>

	<%	 if (latest_input_document = purchased_item.latest_input_document) &&
			(page_corrections = latest_input_document.page_corrections)
	 %>

	webshop_file_uploader.setDocumentCorrections(<%= latest_input_document.id %>,
					<%= raw_json page_corrections.to_json %>, <%= raw_json latest_input_document.status.to_json %>);

	<% end %>

	webshop_file_uploader.setPurchasedItemStatus(<%= purchased_item.id %>, '<%= purchased_item.status %>');

	<% end %>

	webshop_file_uploader.init();
</script>
_file_uploader_control.rhtml

CAN'T STYLE IT

 CAN'T REALLY MAINTAIN IT

CAN'T REALLY TEST IT

GETS EASILY BLOATED

RUBY LOGIC IN VIEWS




what are cells, exactly?




cell is a partial 

wrapped in controller


cells are self-contained


they CAN BE WRITTEN TO HAVE API


THEY CAN BE TESTED

THEY ARE EASIER TO CONTROL

how to create a cell


    
        class FileUploaderCell < Cell::Rails
  helper ApplicationHelper

  def attach_files(opts)
    @purchased_order = opts.delete :purchased_order
    @purchased_items = opts.delete :purchased_items

    @options = default_uploader_options
    @options.merge! purchased_order_opts(@purchased_order)
    @options.merge! attach_files_opts
    @options.merge! opts
    render :view => :display
  end

  def show_order(opts)
    @purchased_order = opts.delete :purchased_order
    @purchased_items = opts.delete :purchased_items

    @options = default_uploader_options
    @options.merge! purchased_order_opts(@purchased_order)
    @options.merge! show_order_opts
    @options.merge! opts

    render :view => :display
  end

  protected
  def default_uploader_options
    {
          :product_element_selector => ".PurchasedItem",
          :upload_link_selector => ".FakeUploadLink img",
          :list_element_selector => ".Uploaded ul",
          :remove_link_selector => ".Remove img",
          :thumbnail_selector => ".Thumbnail img",
          :corrections_selector => ".UploadFileTable",
          :accept_runs_processing => false,
          :in_basket => false,
          :require_file_before_payment => false
    }
  end

  def attach_files_opts
    {
          :use_advanced_approval => true,
          :in_basket => true,
          :production_order_status => false
    }
  end

  def show_order_opts
    {
          :accept_runs_processing => true
    }
  end

  def purchased_order_opts(purchased_order)
    if purchased_order.present?
      {
        :documents_preflight_data => purchased_order.documents_preflight_data,
        :purchased_order_id => purchased_order.id,
        :use_advanced_approval => purchased_order.proof_kind == 'soft_proof',
        :production_order_status => (purchased_order.production_order ? purchased_order.production_order.status : false)
      }
    else
      {}
    end
  end

  helper_method :options_json, :purchased_items, :has_document_corrections, :input_document_corrections, :input_document_status
  def options_json
    raw_json @options.to_json
  end

  def purchased_items
    (@purchased_items + @purchased_items.map(&:parts)).flatten
  end

  def has_document_corrections(purchased_item)
    !!(purchased_item.latest_input_document && purchased_item.latest_input_document.page_corrections)
  end

  def input_document_corrections(purchased_item)
    raw_json purchased_item.latest_input_document.page_corrections.to_json
  end

  def input_document_status(purchased_item)
    raw_json purchased_item.latest_input_document.status.to_json
  end

end
    
cells/file_uploader_cell.rb

how to create a cell


    <script type="text/javascript">
	var webshop_file_uploader = new WebshopFileUploader(<%= options_json %>);

	<% purchased_items.each do |purchased_item| %>
		<% if has_document_corrections purchased_item %>
			webshop_file_uploader.setDocumentCorrections(<%= purchased_item.latest_input_document.id %>,
						<%= input_document_corrections purchased_item %>,
						<%= input_document_status purchased_item %>
			);
		<% end %>

		webshop_file_uploader.setPurchasedItemStatus(<%= purchased_item.id %>, '<%= purchased_item.status %>');
	<% end %>

	webshop_file_uploader.init();
</script>
cells/file_uploader/display.rhtml

cells can have helper methods

helper_method :options_json, :purchased_items, :has_document_corrections, :input_document_corrections, :input_document_status
def options_json
  raw_json @options.to_json
end

def purchased_items
  (@purchased_items + @purchased_items.map(&:parts)).flatten
end

def has_document_corrections(purchased_item)
  !!(purchased_item.latest_input_document && purchased_item.latest_input_document.page_corrections)
end

def input_document_corrections(purchased_item)
  raw_json purchased_item.latest_input_document.page_corrections.to_json
end

def input_document_status(purchased_item)
  raw_json purchased_item.latest_input_document.status.to_json
end
CELLS/FILE_UPLOADER_CELL.RB

cells can BE CACHED

cache :complex_data, :expires_in => 10.minutes
def complex_data
  @data = lots_of_joins_method
  render
end

# or
cache :complex_data, :expires_in => 10.minutes, :if => Proc { |cell, options| cell.current_user.is_admin? }

# or 
cache :complex_data do |cell, options|
  "user/#{options[:user].id}"
end

# or
cache :complex_data, :versioner

def versioner(options)
  "user/#{options[:user].id}"
end

CELLS/FILE_UPLOADER_CELL.RB

CELLS CAN BE TESTED

class CartCellTest < Cell::TestCase
  test "show" do
    invoke :show, :user => @user_fixture
    assert_select "#cart", "You have 3 items in your shopping cart."
  end
end
    
test/cells/cart_cell_test.rb




documentation is available at

https://int.puzzleflow.com/projects/framework/wiki/Cells

cells

By Michał Matyas