Jes
Jes

Reputation: 343

Ruby, Sinatra views and class methods

I'm learning how to use Sinatra. I figured out that when I pass object as locals, e.g.:

product = FetchProduct.new.call(id) #function finds exact Product instance
erb :"products/show", locals: { product: product }

I can use product object in my views with all instance methods I declared. But I can't use any class method, any attempt to do so gives me uninitialized constant error. What should I do if I want to use Product.format_price(product.price) method? Is there any way to pass class methods to Sinatra views?

Upvotes: 0

Views: 539

Answers (2)

Yorkshireman
Yorkshireman

Reputation: 2343

It's generally a bad idea to run that kind of logic in your views. Best practice is to, wherever possible, serve to the view whatever it needs.

NB the reason you can't run the class method in your view is because Product is not accessible in your view and, to be honest, it shouldn't be if you want to follow MVC principles.

If it's just the format_price method you need in the view (especially since you seem to be passing an instance of Product into Product.format_price which is rather strange and a big code smell), then either create a helper method called format_price that is accessible by the view or, probably better, create a helper method called format_price in your controller (or in a helper module included in your controller) and pass the return value as a local i.e.

get '/' do
  product = FetchProduct.new.call(id)
  erb :'products/show', locals: { 
    product: product, 
    price: format_price(product)
  }
end

private

def format_price(product)
  # awesome formatting logic
end

Upvotes: 0

B Seven
B Seven

Reputation: 45943

klass = const_get( product.class )
klass.format_price

But that doesn't really make sense because you already know you want Product.format_price. So why don't you use Product.format_price?

Upvotes: 1

Related Questions