How I can modularize Rails model? - ruby

I'm implementing several classes which does not have data by itself, just logics. These classes implements access control policy to date which depends on several parameters taken from data from other models.
I initially try to find answer to "Where to store such classes?" here, and the answer was apps/models directory. That's ok, but I like to clearly separate these classes from ActiveRecord inherited classes in hierarchy, both as file and class.
So, I created classes inside Logic module, like Logic::EvaluationLogic or Logic::PhaseLogic. I also wanted to have constants which passed between these logics. I prefer to place these constants into Logic module too. Thus, I implemented like this:
# in logic/phase_logic.rb
module Logic
PHASE_INITIAL = 0
PHASE_MIDDLE = 1000
class PhaseLogic
def self.some_phase_control_code
end
end
end
# in logic/evaluation_logic.rb
module Logic
class EvaluationLogic
def self.some_other_code
Logic::PhaseLogic.self.some_phase_control_code(Logic::PHASE_INITIAL)
end
end
end
Now, it work just fine with rspec (It passes tests I wrote without issues), but not with development server, since it can't find the Logic::PHASE_INITIAL constant.
I suspect it's related to the mismatch of the autoloading scheme of Rails and what I wanted to do. I tried to tweak rails, but no luck, ended-up with eliminating module Logic wrap.
Now the question I want to ask: How I can organize these classes with Rails?
I'm using 3.2.1 at this moment.
Posted a follow-up question "How I can organize namespace of classes in app/modules with rails?"

I am not sure whether I really understand your classes, but couldn't you create a Logic module or (I would rather do this:) PhaseLogic and EvaluationLogic objects in /lib directory?
It is not said that "Model" is always descendant of ActiveRecord. If the object belongs to "business logic" then it is a model. You can have models which do not touch database in any way. So, if your classes are "business objects", place them in 'app/models' and use like any other model.
Another question is whether you should use inheritance or modules - but I would rather think about including a module in PhaseLogic, and not about defining PhaseLogic in a module. Of course, all this depends heavily on the intended role of your objects.
Because in Ruby the class of object is not important, you do not need to use inheritance. If you want to 'plug' the logic objects into other objects, just take care that all '*Logic' classes have the required methods. I know that all I said is very vague, but I think I cannot give you some more concrete suggestions without knowing more about the role of these objects.
Ah, and one more thing!
If you find yourself fighting with Rails class autoloading, just use the old require "lib/logic.rb" in all the classes where you are using Logic::PHASE_INITIAL constants.
In this case I suppose that your problem was caused by different order of loading. The logic/evaluation_logic.rb has been loaded before logic/phase_logic.rb. The problem may disappear if you create logic.rb somewhere, where class autoloading can find it, and define these constants in that file.

Don't name your classes or modules Logic use specific names. Start with extracting logic into separate classes and then try to break them into smaller ones. Use namespaces to distinguish them from each other in lib folder, after this steps you would be able to extract some logic parts to separate gems and reduce codebase and complexity of application. Also take a look into presenter pattern.

Related

What is a good practice for dependency injection in Ruby?

I've been reading Sandi Metz's Practical Object-Oriented Design in Ruby and many sites online discussing design in Ruby. Something I've had a hard time fully understanding is the proper way to implement dependency injection.
The internet is flooded with blog posts that explain how dependency injection works in what I think is a very partial way.
I understand that this is supposed to be bad:
class ThisClass
def initialize
#another_class = AnotherClass.new
end
end
While this is a solution:
class ThisClass
def initialize(another_class)
#another_class = another_class
end
end
And that I could send the AnotherClass.new like this:
this_class = ThisClass.new(AnotherClass.new)
That is the approach that Sandi Metz recommends at least. What I don't understand is where should a line like that go? It has to go somewhere and generally in examples of this what's shown is a line like that being placed totally outside of any class, method, or module as if I'm simply entering it all by hand in IRB for testing purposes.
This post (among others) suggests this different approach:
class ThisClass
def another_class
#another_class ||= AnotherClass.new
end
end
Jamis Buck would take a similar approach like this:
class AnotherClass
end
class ThisClass
def another_class_factory(class_name = AnotherClass)
class_name.new
end
end
However, these two examples both preserve AnotherClass's name inside ThisClass, which Sandi Metz says is one of the main things we're trying to avoid.
So what is the best practice for doing this? Should I make a 'dependency' module filled with methods that are factories for objects of each class in my application?
Something I've had a hard time fully understanding is the proper way to implement dependency injection.
I think the best definition of a "proper" implementation is one that adheres to the SOLID principles of object oriented design. In this case mostly the Dependency Inversion Principle.
In this regard, this is the only presented solution that does not violate the DIP(1):
class ThisClass
def initialize(another_class)
#another_class = another_class
end
end
In all other cases, ThisClass has a hard dependency on AnotherClass, and can not function without it. Furthermore, if we wish to replace AnotherClass with a third, we need to modify ThisClass, which is a violation of the Open Closed Principle.
Of course, in the example above, naming the parameter and instance variable another_class is not ideal, since we do not now (and do not need to know) what object is passed to us, as long as it responds to the expected interface. This is the beauty of polymorphism.
Consider the below example, taken from this ThoughtBot video on DIP:
class Copier
def initialize(reader, writer)
#reader = reader
#writer = writer
end
def copy
#writer.write(#reader.read_until_eof)
end
end
Here you can pass any reader and writer objects that respond to read_until_eof and write respectively. This gives you full freedom to compose your business logic using different pairs of read and write implementations, even at runtime:
Copier.new(KeyboardReader.new, Printer.new)
Copier.new(KeyboardReader.new, NetworkPrinter.new)
Which brings us to your next question.
It has to go somewhere and generally in examples of this what's shown is a line like that being placed totally outside of any class, method, or module [...]
You are correct. While object thinking involves modelling the domain with well isolated, decoupled, and composable objects, you will still need to define how these objects interact, in order to implement any business logic. After all, having composable objects is no good unless we compose them.
The analogy that is often made here is to think of your objects as actors. You are the director, and you still need to create a script(2) for the actors to know how to interact with each other.
That is, you need an entry point into your application. A place where the script starts. This might itself be an object--normally an abstract one. In a command line application, it can be your classic Main class, and in a Rails application it can be your controller.
This might seem strange at first, because the focus of object thinking is on modelling concrete domain objects, and a great deal of all writings on the subject is dedicated to this effort, but just remember the actor-script metaphor, and you'll be on your way.
I strongly recommend you pick up the book Object Thinking. It does a great job explaining the mindset behind object oriented design, without which knowing the language specific implementation details becomes rather futile.
(1): It is worth noting that some proponents consider storing an instance of another class in an instance variable an anti-pattern, but in Ruby, this is fairly idiomatic.
(2): I am not sure if this is the origin of the term script in programming in general, but maybe some historian can shed some light on this.

HMVC how to separate the modules?

I'm making a leave management (HRM) website. I'm using codeignitor HMVC to build this. Following features are included in this site:
A table to display a summary of leaves.
A table for leave types like annual, MC, urgent, other...
I was thinking to create two modules for leave_summary and leave_types, but my friend told me it is useless.
According to HMVC architecture we are trying to create self contained modules for reusability. If I'm creating a different module for leave types, I should be able to reuse it and module itself needs to be self containing. But I can't use leave_types module anywhere else.
My friend asked me to put all the leave related stuff in one module called leave. This sounds strange to me as I found lots of examples people are trying to separate things out.
Do we only need to separate the modules which can be reused in the future (ex: login module, image_gallery module, profile module) and keep all others things inside a one module?
(according to the above example I have to keep everything related to leave in a one module
ex: leave_type, leave_requests, leave_summary will be placed inside the leave module)
What are the benefits I will get, if I separate the leave_type, leave_requests, leave_summary etc... into separate modules?
Will I be able to reuse them? If so How?
In HMVC model classes and other assets can be exchanged among the modules, so how can I call it a self-contained module or a separate entity as it is depending on another module?
(ex: I have to call leave_type module's model class inside the leave_summary module to show the leave type name in a table.)
I'm little lost here. Please help me to understand. Thanks a lot!
As i work lot of MVC projects. And I am agree with your friend.
May times this question arise when i used join that i have to choose in which one module i should go for write query. If you write in one model may next developer will write in another one model.
So according me it is best to keep same type of tables which are handling relation and using for same behavior use this approach like leave model, profile model etc.

Using an object oriented approach in Ruby

I have two classes, Class A and Class B.
I've recently noticed that they share a lot of the same code. For example:
def viewable_by?(user)
super || clinic.has_staff_member?(user) || user.system_admin? || self.person == user.person
end
I want to minimize the code duplicated between the classes. But in refactoring, I've found that much of it doesn't fit neatly into one class that falls cleanly in the Single Responsibility Principle. I want to put it all into a single module, but the methods will have to do with time formatting, viewing permissions, and a few other things.
As I see it, I have a few choices. (And I bet you can suggest others.) From an object oriented point of view, which approach should I go with and why?
Use one single module shared between both of the classes. It may
not have a specific single responsibility, but it does clean up the
code significantly, and keeps it all in one place.
Make tiny classes and mix in to both classes as modules. They
will all have a single responsibility, but there will be many of
them, some of which may only have one method. Seems like a waste.
Perhaps use a presenter for things like time formatting, and a
permissions module shared between both classes. Perhaps "cleaner,"
but methods are going to be everywhere.
Another possibility I haven't yet considered?
EDIT
This question had previously mentioned Clinic::Appointment and Clinic::Visit classes, rather than A and B. Answers may refer to appointments and visits.
This is a neat question because it deals in a great way with the overall strucuture of your project. I understand that Appointment and Visit are separated things, and an Visit don't need to be linked to an Appointment.
For authorization methods, like viewable_by?, I recommend move all authorizations to other place - you might want to check the cancan structure, that have worked well for many Rails projects, and most likely will work well for any application, even coding an authorization system yourself. So in part, my answer for you is to use (3).
However, since not all code that is shared by the two classes are for authorization purposes, I would try to classify a set of methods, and give an answer for each class of methods you could think of. For method classes that have a similar behavior I would try to encapsulate in a module and include it (so just like (1), but in smaller parts). For example one module HasVisitors with methods like got_on_time? and was_conclusive? (well, maybe not the best examples, but you get it). When your model has a broader scope, like Authorization, that is present in most of your classes, then it is time to go to (3).
I suggest you stop and think again if you should have a Visit class apart from Appointment and it relationship, but not now. After got at home, have fun, take it off from your head, then think again next day.
Would the design be clearer if you shifted the responsibilities? e.g. user.can_view?(resource)

How to identify necessary classes and modules of Ruby software?

Say I am writing a Ruby gem. I want to design classes and modules going to be used.
How to identify them?
Where do I need classes and where do I need modules?
Your question is about one of the main design feature of the Ruby language.
Basically, you can see module as collection of tools, and class as collection of objects which are able to mix with those tools.
Ruby faq says about modules :
Modules are collections of methods and constants. They cannot generate instances.
When you want to provide something, you'll need a class. You can do a MyClass.new, you cannot with a module : MyModule.new won't work.
On the other hand :
Classes may generate instances (objects), and have per-instance state (instance variables).
When you want to provide a way of doing something, you'll a need a module. You can do a MyModule.doSomething(SomeParams). You can also do that with a class methods, but you won't be able to do some mix-in with it.
See this faq for a more detailed answer.
This is a object oriented design task, if you are really new to that I would recommend to study a book like Head First Object-Oriented Analysis and Design. I usually try to identify the core actors/concepts in the business model to discover which classes I need.
A basic rule is to use classes when you need to maintain some states, and modules when there is no need of maintaining states. Ruby has several uses for modules Ruby, there are several articles about this topic in the Practicing Ruby blog: part 1, part 2, part 3, part 4
I use to think of Modules stricly as as behaviour capsules and Classes as state and behaviour capsules (from encapsulation).
So, if you want to encapsulate a behaviour use a module. Otherwise use a class.

Using mixins vs calling a method directly

I'd like to know when is the best time to use mixins vs calling a method directly.
For example, consider HTTParty. On one of its examples https://github.com/jnunemaker/httparty/blob/master/examples/basic.rb
you can use HTTParty.get('http://twitter.com/statuses/public_timeline.json') or you can create a class that includes HTTParty and then use it as you would calling HTTParty itself.
What's the difference with me just creating something like this:
class Partay
#base_uri = 'http://localhost:3000'
def self.post(endpoint, options)
HTTParty.post(#base_uri + endpoint, options)
end
end
versus the given example:
class Partay
include HTTParty
base_uri 'http://localhost:3000'
end
True that in such a trivial example perhaps using the include would save more characters, but I'd imagine on a much more complicated class it doesn't really make a difference.
A few clarificatory questions:
Would this be related to a composition vs aggregation argument? Is there any design or architecture best practice regarding this? Should I treat mixins as some sort of inheritance and use them as such (inheritance if it's an is-a relationship, composition if it's a has-a relationship, etc.)? Should I only mixin a module if it was intended to be done so (because docs say it expects certain methods from you, like Enumerable) or is it just good practice to do so? Would using a mixin mean a tighter coupling between the module and my class (and is it relatively good or bad in general)?
In the given example, there is not much difference, other than the syntax is much more friendly with the mixin, and could potentially become a DSL that you can use later.
More generally, mixins allow you to use these same functions in different classes without repeating yourself, and without extending another class (mixins are, for example, a way of working around the fact that ruby does not allow multiple inheritance). This favours reuse and goes towards the DRY philosophy dear to the ruby users. As ruby is duck-typed, mixins allows you to take full advantage of polymorphism without inheritance.
Another great advantage of mixins is that they can be added at runtime, so this means you can add behaviour to a class "dynamically".
Update: I personally prefer using modules as mixins, rather than calling methods on it as the methods then become part of your class, which means that they can access the other members of the class. I’m however reluctant to call it a is-a relationship, even though that’s what it is in practice. As the “Well-Grounded Rubyist” says, classes model entities or things (class names tend to be nouns), modules encapsulate properties or characteristics (module names tend to be adjectives).

Resources