Ruby/Rails: The right way to override rails methods? - ruby-on-rails

I'm creating a rails gem that adds functionality to Rails' fields_for method, and I'd like it to be callable from any form builder. To keep things concise, inheritable (from form_for, nested_fields_for, etc), and backwards-compatible, I'm beginning to think overriding the fields_for method is the best way to go about it.
I've not done this before though, and I can envision some ugly problems. Specifically:
I need to call the original fields_for method (via alias_method) in the new one. If Rails changes how that method works in the future, I'm guessing my gem will break all fields_for functionality(?)
If another gem overrides fields_for, I suspect either my or the other gems' fields_for method will be ignored(?)
In general, the idea of overwriting an existing rails method just seems pretty shifty.
I'm sure this is something other developers face, and I'm just wondering - what's the standard approach to overwriting rails methods? Is it a big taboo amongst better developers? Is there another approach to this sort of issue? Should I just sod my attempt for a concise, elegant solution and do it up with a different method name after all?
Any suggestions appreciated.

Rather than overriding your methods, I would take a page from simple_form and formtastic. Both of which effectively change the form_for method, but they create a new method on top.
<%= simple_form_for #model do |f| %>
<% end %>
This way you can delate out to form_for for everything you don't respond to, and stay insulated from method signature changes.

Related

Rails - Creating a custom ERB tag for i18n

Since I write so often this in Rails...
<%= t 'whatever' %>
I was wondering: Is it possible to create a custom tag to make it even shorter? Something like...
<%t 'whatever' %>
It would be fun if I could create my custom tags and make them output anything based on its content.
How would such a thing be doable?
PS: I realize that I am just saving just 1 character. As I said it is for fun. And besides, if creating custom tags is not too complicated, it could have even more applications.

Editing multiple objects with simple_form

In the Railscast dealing with Editing Multiple, Ryan shows how to edit multiple objects in batch with form_tag. Is there a good way to do this using simple_form?
The base-case for using form_for or simple_form_for helpers are to hand them an ActiveRecord model...
<%= form_for #zebra do |f| %>
...which doesn't work in this case because you're not creating a form for one single instance of an ActiveRecord model. In the RailsCast, this is why Ryan uses form_tag.
There isn't a simple_form_tag, but you can hand simple_form a :symbol instead. Check out this SO post to see how some folks approached a similar problem. Know that at that point, you're writing a lot of extra code for simple_form to do what the RailsCast code does instead, and you lose a lot of the built-in niceties of simple_form.
There might be really good reasons why you'd battle with simple_form in this non-ideal scenario. If it were me, I'd start with the RailsCast code, get it working, and worry about niceties second. :)

Model methods in views

I have the following piece of code in my view:
<% if #user.get_products.any? %>
<%= f.select('products', #user.get_products.collect { |user| [user.name, user.id]}) %>
Where get_products is making an ActiveRecord query to DB. So I wonder if it actually does two same queries or uses cached result from first query on second call? I tried to check it in server logs - but found nothing. I would also like to know if I can control this behavior somehow, i.e. set/unset cache for this view.
Thanks!
UPDATE:
I think it violates MVC too, but what confused me was IDE warning: "view should not share more than two variables with controller."
However, I am creating somewhat "one page" website, so I need to have #user, #nearest_users, and #user_products in the same view. So I found the following article:
http://matthewpaulmoore.com/post/5190436725/ruby-on-rails-code-quality-checklist#instances
which said
Only one or two instance variables are shared between each controller
and view.
Instance variable hell - when a lot of instance variables are shared
between a controller and a view - is easy to do in Rails. It’s also
potentially dangerous to performance, because you can end up making
duplicate calls on associations unknowingly. Instead, your controller
should only manage one instance variable - and perhaps a second for
the current_user. That way, all calls to associations are loaded “on
demand”, and can be instance-variable-cached in a single place.
This methodology also works out well for fragment caching, because you
can check caches in views before actually loading associations.
For example, instead of having your Blog controller create an instance
variable for both #post and #related_posts, just make a single method,
#post, and give your Post model a related_posts method, so you can
just call #post.related_posts in your views.
To answer your question: Queries in view don't get cached.
What's more, Ruby codes in ERB template are executed using eval, which is very inefficient.
So my advice is: avoid writing logic in view, it's kind of bad practice.

Ruby on Rails div_for vs <div>

I'm new to Ruby on Rails. In my erb files, is there any reason to use the div_for helper over just typing out the <div> tags and setting the properties as HTML? What advantage is there to using div_for, and is there a recommended best practice?
I think the main reason people use the div_for helper is because it can accept an array of ActiveRecord objects as an argument. That way it becomes a short-hand combination of a loop iterator and a tag generator.
<%= div_for(#people, :class => "foo") do |person| %>
<%= person.name %>
<% end %>
div_for does some "magic" for you, in that it sets the class and ID of the element it generates.
There is no reason to choose it over a simple <div> tag if you don't intend to use those properties, or intent to use different values for them.
There is no strong convention either way. I've been writing Rails code for years and have literally never used it, put it out of your mind, it doesn't matter. There are far, far more important decisions to make, like choosing erb or haml or slim, or deciding whether to adpot CoffeeScript. Decisions that will fundamentally alter the way you write Rails code.
In many cases, rails 'helpers' are like training wheels on a bicycle. They help when you are just starting out, but at some point, you jettison the training wheels and start doing wheelies, sliding skids, and jumping homemade ramps.
But helpers vary, some are so helpful you never get rid of them, others get in the way when you want to start doing wheelies.
If you find using any particular 'helper' is cramping your style, stop using it!

way of implementing links in rails

I have a project I am doing in rails. I want to implement this sort of links
{user} has {action} on {file} in {project}
each of the words wrapped by curly braces are entities in my system (models). how do I implement saving these changes in the project and how do I get all of the changes from the database and display them to the user?
I am using rails 2.3.8 if it matters
example of the links I need to display (image)
There are some plugins available to keep track of activities in models:
https://github.com/grosser/record_activities
https://github.com/linkingpaths/acts_as_scribe
https://github.com/face/activity_streams
I normally use acts_as_scribe, it's the simplest of them.
I would recommend acts_as_audited. It works very well. It saves all your changes on a model in the form of a hash, so using it becomes as easy as
audit = Audit.first #just for example
In your view
<%= link_to User.find(audit.user_id), user(:id => audit.user_id) %> has
<%= audit.action %>
Of course you will have to customize how your messages will finally appear. And of course its better not to use find methods in your view. I've used it here just for illustration purposes.

Resources