Equivalent of Django Signals for Rails? - ruby-on-rails

In Rails, the closest I've seen to Django Signals are Observers. The problem with them is that they're restricted to triggering callbacks on hardcoded events related to a model's lifecycle.
Django signals can be created anywhere, triggered anywhere and handled anywhere. The model lifecycle callbacks are just regular signals that happen to come built-in and that are triggered by the ORM.
Does anyone know of a similarly general solution for Rails? It could be some generic Ruby library, not tied to Rails, which would be even better.
Edit: Observer is the closest thing, but it's not what I'm looking for. It's a one-to-many solution. Anyone can listen, but only the originating object can post. I'd like something where you declare a signal, and anyone can trigger it as well as handle it. Also, I don't like the fact that the Ruby Observer dictates that the handler have an #update method. I'd like to be able to pass any method reference with the appropriate signature.
I could use the Ruby Observer to implement my own such broker, but I'm trying to learn if someone already did it.

I think a closer equivalent than Rails' Observer is the standard Ruby Observable module. It lets you add a list of observers to an object and the object can then send notifications to the observers when it changes.

What about the 'wisper' gem? https://github.com/krisleech/wisper
Wisper is a Ruby library for decoupling and managing the dependencies
of your Ruby objects using Pub/Sub.
It is commonly used as an alternative to ActiveRecord callbacks and
Observers to reduce coupling between data and domain layers.

Perhaps acts_as_state machine will help. Most of this functionality has recently been baked into Rails edge.

I just implemented a gem with that. https://github.com/pkoch/django_signal/

Ruby gem 'watchable' is the most appropriate choice
https://github.com/jbarnette/watchable
It has a syntax that is very familiar to Django's (and other frameworks, like Qt and many others).

Related

Rails generic controller and views

I've been looking at Administrate source code and would like to know if it's a good practice or not the use of a generic controller and what implications it would have, like code complexity, performance degradation, etc.
Sometime ago, there was a gem inherited_resources that provide this feature, but since Rails 3.0 or 3.1 has been said we no longer need them.
So, since I have some very simple models (with only two or three fields) I could create a generic view and controller to manipulate them and save a lot of lines of "duplicated" code. Although I'm afraid, by avoiding repetition I could be creating another monster.
I've been looking for a Rails way to do this, but failed, so I would thanks some advice.
Note: I'm not looking to implement or use an admin dashboard, but use in my application instead
All Rails admin-panel implementations will make you hurt when you will try to make something more complex than stupid simple CRUD-application. I recomend you not to use such solutions. I had experiece in usage three different Rails's admin-panels and all of them had bad design and a lot of limitations. They are hard to mantain and extend their functionality.

Generate and send xml on model save

I need to generate xml from a model and send it to a web service on model save.
I'm sure this is a common case and should be straight forward. Just create a job on after_save callback that generates the xml and sends it to the endpoint.
Since I'm new to Ruby on Rails I'm not to sure how to handle this though. My questions are more about code organization. It's not unlikely that this api connection will be discontinued in the future so I need a clean modular way to get rid of it. Would it be best practice/convention to put this in a separate gem? Can gems actually add jobs to an existing rails queue? Can gems create migrations on install? I'll probably need to add a model to keep track of the api sync. How about dropping a table on gem uninstall? Or should I not use a gem for this at all?
I realize these are broad and basic Ruby on Rails questions but I'm kind of drowning in documentation. I'm just hoping for some examples and/or advice and maybe some pointers to relevant documentation. Thanks.
Gem installs/uninstalls are unrelated to apps, they live on different level and do not khow anything about your app code, db and so on unless they are loaded.
Gems for rails can provide rake tasks and/or generators, for example you can look into devise gem structure on how it does this.
But i'd advise against moving code to a gem before you know you have to, like for example when you need to reuse it in different project.
To reuse code inside single project - use mixins/concerns
In general:
don't make it a gem
it's an unnecessary world of pain, pretty much always,
never make anything a gem unless you intend to use it in the same way in 3+ applications
don't extract it into a concern either,
it doesn't seem very likely that you'll do the same operation on multiple models, code reuse seems to not be an issue here and you can actually reuse code more efficiently using service classes too
a lot of experienced Rails programmers regard this practice as concerning, forgive the pun. It seems this view is not shared by the Rails development team, but at least from my experience writing service classes seems like unnecessary complexity until your project grows enough and then you need to refactor a BUNCH of stuff and you realize you would have been better off ditching concerns from the start
use a service class instead and delegate the necessary methods to it from the model
this will leave you with a clean interface to extract later and will also allow you to use dependency injection if you need to mock your XML service for tests
don't tie API requests to model callbacks, there's usually just 2-3 places where you need to do something with the API and a bunch of other cases where that may not be the case, imagine:
tests,
or if you get a requirement to implement cache column,
or a "number of visits" column
or a gem like Paperclip that thought that it wanted to add something to the model but changed his mind and instead of that just touched updated_at
or any such trickery which will make you a grandiose API spammer and a sufferer of VERRRRY slow database updates
if you DO tie API requests to model callbacks,
then you better make sure that error handling is done properly and that timeouts etc don't rollback or delay your DB operation,
best way from my experience is to run these things through ActiveJob + one of the backends (though obviously not the :inline backend and ideally one of the backends which don't use your main database and allow asynchronous job submission - sidekiq comes to mind as a candidate)

Should I use ActiveSupport::Notifications to implement activity feed in rails

I'm thinking about my options here.
implement it with after_create/after_update hooks in activerecord with models.
using ActiveSupport::Notifications to decouple activity feed objects with models.
use observer.
I wasn't able to find much information about the second approach. And I imagine the third one is kinda like the first one. Am I using ActiveSupport::Notifications wrong? Why?
Found this post about using ActiveSupport::Notification to implement email notifications. It might be similar with activity streams.
http://alma-connect.github.io/techblog/2014/03/rails-pub-sub.html

How can I document implicit methods inside of rails models?

I'm using YARD on my Rails project and was wondering how I would go about documenting inherited/runtime methods on a Rails model? For instance documenting the existence of a first_name attribute on a User model.
You can't do that, IMHO.
The trouble is that those methods don't really "exist"; They are "created on the fly" via method_missing hooks, the first time they are invoked, on runtime.
Other documentation generation systems have ways to declare "implicit" methods. For example NaturalDocs has a function keyword that allows you to create functions that only exist on the comments. I'm not familiar enough with YARD, but it seems it doesn't have a similar functionality.
Good luck!

Ruby on Rails: Do you recommend using Observers?

I notice it's used primarily for sending emails. Let's say I want to send an email after every comment is created.
Is using Observers really necessary when you could just place the Mailer.deliver_email(user) in your comments_controller.rb's create action instead?
For proper programming practices, yes. The observers decouple the code and make sure it stays maintainable.

Resources