0

I have a mode to put my code of controller in lib/ to reduce the code of the controller, I don't know if this works with my instance variables. I need some pass the action of controller to a lib/, to make a sample call require or include in action, some to organize my code more.

The action is:

def calculate_ship
  pacote = Correios::Frete::Pacote.new

  @products = buy_cart.line_items

  @products.each do |p|
    p.product.length = 16 if !p.product.length
    p.product.weight = 0.3 if !p.product.weight
    p.product.width = 11 if !p.product.width
    p.product.height = 6 if !p.product.height
    @item = Correios::Frete::PacoteItem.new :peso => p.product.weight, :comprimento => p.product.length, :largura => p.product.width, :altura => p.product.height
    while p.quantity > 0
      pacote.add_item(@item)
      p.quantity -= 1
    end
  end

  frete = Correios::Frete::Calculador.new :cep_origem => "95520-000",
    :cep_destino => params[:cep],
    :encomenda => pacote
  servicos = frete.calcular :sedex, :pac
  @pac = servicos[:pac].valor
  @sedex = servicos[:sedex].valor
  flash[:error] = servicos[:sedex].msg_erro
end

How to move this into lib/? I'm not accustomed to programing seriously with lib/, etc.

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
overallduka
  • 1,520
  • 19
  • 27
  • Simply “moving” code to a module that you then `include` in the controller only gives the illusion of less code, but instead you have the same amount of complexity dispersed throughout several files making it harder to understand what’s going on in the controller. – Andrew Marshall May 26 '13 at 17:22

1 Answers1

1

Instead, how about moving your logic into model & private methods. something like this?

Controller

def calculate_ship
  Model.products = buy_cart.line_items
  Model.set_defaults
  @products = Model.items
  servicos = calc_costs
  @pac = servicos[:pac].valor
  @sedex = servicos[:sedex].valor
  flash[:error] = servicos[:sedex].msg_erro
end

private
  def calc_costs
     frete = Correios::Frete::Calculador.new :cep_origem => "95520-000",
    :cep_destino => params[:cep],
    :encomenda => pacote
    frete.calcular :sedex, :pac
  end

Model

attr_accessor :pacote, :products
 def initialize
    pacote = Correios::Frete::Pacote.new
 end

def self.set_defaults
      products.each do |p|
        p.product.length = 16 if p.product.length.empty?
        p.product.weight = 0.3 if p.product.weight.empty?
        p.product.width = 11 if p.product.width.empty?
        p.product.height = 6 if p.product.height.empty?
      end
end

def self.items
  products.each do |p|
   @item = Correios::Frete::PacoteItem.new :peso => p.product.weight, :comprimento => p.product.length, :largura => p.product.width, :altura => p.product.height
        while p.quantity > 0
          pacote.add_item(@item)
          p.quantity -= 1
        end
  end
end

PS: I didn't understand the code logic on what its actually doing as the complete code was not given & also the language looks like English but its not English. so, This is pseudo-code might have some errors but I hope this would give you atleast an idea on how you can move code from controller into the model/private methods. controllers actions should only be used to instantiate instance variables & call methods on objects. Remember, fat models & skinny controllers!.

Hope it helps

[edit] F.A.Q

Q1. the Model in you code in controller can be someone Model? i talk this because this action is in my Cart controller, seems that the model should not be product?

Ans: I am not sure I fully understand what you mean by the Model in you code in controller can be someone Model? Are you asking that where this model code should do? Its actually simple, if this mode code is related to Cart, put it in Cart's model & if its related Product, put it in Product's Model.

Q2. this attr_accessor :pacote, :productsis for the pacote valid in all my app ? and the products to be able to pick up the product model Product?

Ans: attr_accessor :pacote, :productsis declares getter/setters. Please see What is attr_accessor in Ruby?

Community
  • 1
  • 1
CuriousMind
  • 33,537
  • 28
  • 98
  • 137
  • Many duvids man, but the principal is: the `Model` in you code in controller can be someone Model? i talk this because this action is in my Cart controller, seems that the model should not be product? Im a big questioner ;P, this `attr_accessor :pacote, :products`is for the pacote valid in all my app ? and the products to be able to pick up the product model Product? Sorry by the questions but i need understand this, very thanks,from now on, thank you very much. – overallduka May 26 '13 at 18:57
  • @overallduka I don't have much context around the question, due to missing code but anyways, I have tried to guess what you might have meant & answered it. – CuriousMind May 27 '13 at 05:50
  • Thanks much man, i will write my code best now, if have more some reference to write minor code or organize im atempt, thanks. – overallduka Jun 05 '13 at 18:54