Is there a reason why ActiveRecord's bang methods are public, but not documented nor mentioned anywhere?
For example, where!, order!, limit! and others are all public and used by their non-bang counterparts.
I understand that they change the query object instead of its clone (and caution is necessary), but so do other bang methods, which are usually very well-documented.
They want to keep the API to be immutable, see the comments on this commit:
https://github.com/rails/rails/commit/8c2c60511beaad05a218e73c4918ab89fb1804f0
And as for all undocumented methods (with # :nodoc:), they are part of the private API.
You should not use them as they could be removed without a warning.
hth
Disclaimer: I'm not a RoR contributor, so if there is some RoR specific reason to it, I don't know.
As you said, they are wrapped by their non-bang counterparts. The where method for example checks if the method has the correct number of arguments and applies a the current scope to it. Moreover it provides the polymorphic behavior outlined in the documentation.
Source: https://github.com/rails/rails/blob/4c0d6680ee011b822e6beaa1ee84f835e89550a1/activerecord/lib/active_record/relation/query_methods.rb#L550
My impression is that they are this way for abstraction reasons. The bang methods implement a lower level of functionality, while the non-bang methods provide a more user-friendly interface. As to why they are not documented but are public, I think the library authors wanted to provide the option to use them if you really know what you're doing.
Related
I am a Java programmer mostly, and it's actually amazing that we don't have to worry about a lot of security concerns that php or even rails developers have to worry about. We have to worry about them, but I think our job is actually a lot easier. You just use Java (already big bonus points there) and use Spring with Spring security... and you're basically done. Java and servlets are actually really good in this respect.
Now that I'm working in Rails, I think the biggest security concerns that I am the most scared of are parameters - both in the ones that are coming from the controllers (since they dynamic hashes, unlike in SpringMVC) and having to include more hidden values in forms.
But that got me thinking - you really have to be careful what you accept when you create new models or even update models. If you just blindly pass in parameters to your models, bad things can happen. In fact, things like the user role and stuff could be changed if you're not too careful.
It's almost like I want to write the setter code by hand to make sure it's not overwriting something that it shouldn't. And even if there's a framework mechanism to handle this... I would still want to test every risky model attribute just to be extra sure that it won't get overwritten on a create and on an update.
As much as Java gets a bad rep about productivity, it feels like it handles this stuff a lot better.
Anyway, my question is - what is the best resource/tips/advice for dealing with common security pitfalls/concerns/gotchas using rails - especially geared towards a Java/Spring developer who got used to working in a more stateful environment.
Even better, what would be a good checklist to go through every once in awhile?
And last, what tests would you recommend to make sure things are solid?
At least for your concern about assigning data to your model objects without proper checking, look into the attr_accessible declaration; it allows only specified attributes to be assigned via the bulk assignment:
user = User.new(params[:user])
user.approved = params[:user][:approved]
user.role = params[:user][:role]
You might find the entire 27th chapter of the Ruby on Rails 3rd edition book useful. (I haven't updated my 4th Edition book yet, not sure which chapter to recommend from the newer book. :)
I don't use ActiveRecord (I use DataMapper), but as a rule, I never do mass-assignment and I always expressly pass only the attributes I want to change. Rails 3 defaults to escaping all content in your views, unless you expressly output that data raw into into the .erb.
Also, it really bugs me that ActiveRecord doesn't help you out very much if you need to drop down to using SQL for something. You have to escape input yourself, which can expose you to the risk of human error allowing arbitrary SQL to be executed in your queries. DataMapper's underlying DataObjects connection supports prepared statements out of the box and in fact, it would actually require more work to avoid using them.
Rails 3 does have CSRF protection turn on by default too. It also makes session cookies HTTP-only by default, which makes them harder to steal via JavaScript.
I actually think, aside from Rails encouraging the use of mass-assignment, you're pretty well-covered for security.
So, I'm writing a service that, being in rails, I'm pretty indifferent about how people connect. I do auth at the http layer, so if people want xml or json, I could care less.
I'm overriding to_json and to_xml, but I'm using the same arguments for both. 'include this', 'don't include that', etc.
How are other people doing this to check that the behavior is the same? Maybe just set one set of arguments and use them in both methods? Or maybe have methods that verify the JSON.from_xml(myobject.to_xml) == myobject.to_json? I'd like to not have to do all my tests twice if I can help it.
So, I'm answering my own question here. Found another one like it. Has a good explanation of what I was looking for. Long story short, I'm overriding serializable_hash
http://api.rubyonrails.org/classes/ActiveRecord/Serialization.html
How to override to_json in Rails?
PS, I'm still interested in what people are doing. Are they testing JSON and XML formats at all? Are you doing integration tests?
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!
I'm making a little message sending module. It'll handle queuing messages from a request to be picked up by a background worker to send email/SMS (or log appropriately for testing).
Question: is this a Model (under /app/models) or a lib (under /lib).
I'd like some religion on this.
Theory A: (My current theory) Unless you're subclassing ActionMailer::Base or ActiveRecord::Base, etc, your code should go into lib.
Theory B: (Theory I'm leaning towards) Things that are application-specific should be in model. Anything that could be of general use should be in lib.
Theory C: only "data models" should be in 'models'. ActionMailer subclasses break this rule, though.
As far as I know, either way it'll work fine, but I'm looking for any subtle functional or philosophical reasons for one vs. the other.
Thoughts?
Whether or not messages inherit from ActiveRecord or ActionMailer, you likely want a model for any objects that your views and controllers interact with. In your case, they will handle instances of the Message class -- you want a model for that.
As for the message sending module -- extracting out to a library is great if you plan to reuse the code elsewhere where you can just include the module in any class.
Since this is just a "little" message sending module, you might want to start in the model and eventually extract out to a separate module if it could be useful elsewhere or your model gets too messy.
You should probably think more in terms of the underlying business here. Models, as their name suggests, are here to represent (model) some real-world system or process. So, the rule of a thumb should be this: Does this entity play any role in the system I'm trying to express in my application? If the answer is positive then the entity is a good candidate for being a model. However, it'd be perfectly OK to implement the core functionality of your messaging module in some separate library for later reuse and just include it in the model.
I like the 'Data Model' Theory and I try to stick to it when I can, but I think Bensie and Milan have the right idea. If you have views and controllers associated with it, it should be with models. If you are only referencing the functionality from within another class, put it in the lib.
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).