Reputation: 17157
In my app, I want to define a class that my models, views, and controllers will use. My thought was to create a new directory, app/lib
, where I created:
# /app/lib/donut.rb
class Donut
def initialize(sprinkle_color)
@sprinkle_color = sprinkle_color
end
def sprinkle_color
@sprinkle_color
end
end
Now this works fine, but when I added test/lib
, those tests are not run when I run rake test
. I can run rake test:all
which works, but feels wrong.
Is this the right place to put classes, and if so, how do I get them into the tests?
P.S. Why do I need a class like this? Of course, I'm not actually creating a donut. It's a class that takes a set of arguments, and there are many models that have these objects. In addition, there are views that take these objects, or arrays of these objects. Finally, there is code that operates on lists of these objects, and I've put that code as static methods into this class.
Upvotes: 0
Views: 1098
Reputation: 3342
I really dislike using "lib". Instead, I recommend using common design patterns as top-level directory names for other POROs. I do this in Rails projects. So that I have something like this:
app/
models/
controllers/
services/
policies/
validators/
Etc.
A great showcase of this can be found here: http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/
Upvotes: 0
Reputation: 1936
Create folders in the app directory for custom classes but try to make them as descriptive as possible. For e.g. I use custom classes to properly format json for ajax loading datatables so the classes are located in app>datatables
e.g.
app>datatables>users_datatable.rb
class UsersDatatable
[...]
end
And so in the controller action I can render a view using the custom class:
respond_to do |format|
format.html
format.json { render json: UsersDatatable.new(view_context, current_user) }
end
Here's another example that uses prawn pdf to generate a pdf view:
app>pdfs>quote_pdf.rb
class QuotePdf < Prawn::Document
[...]
end
And in the controller action:
respond_to do |format|
format.html
format.pdf do
pdf = QuotePdf.new(view_context, @quote)
send_data pdf.render, filename: "quote_#{@quote.number}.pdf",
type: "application/pdf",
disposition: "inline"
end
end
Testing is easy. Since the custom classes I use are associated with other resources I include the tests with them. i.e. with users, quotes. However you can create separate tests as you have done to be able to run them separately.
I would argue that app>lib
is not descriptive enough. If possible, try and be more specific on what the custom class is actually doing.
Upvotes: 2