Sorting on a unknown property - grails

I’m building a small application, and in part of the UI you can sort some objects (persons). So when I call this url:
http://localhost:8080/addressbook/person/list?sort=name
all works nicely.
However, when I change the URL to the following, my application is throwing exceptions:
http://localhost:8080/addressbook/person/list?sort=thisisanunknowproperty
I get errors like:
Class
org.hibernate.QueryException
Message
could not resolve property: thisisanunknownproperty of: persons.Person
This is really not what I want, of course. The application should just not sort, and not throw exceptions like this. But how do I prevent this behavior from happening?
Thing which come to mind is that I build something in which checks if the property is a member of the allowed properties to sort, but I'm wondering if there is anything out of the box for this which I missed?

As I mentioned via email, take a look at Grails Command Objects which are based around the Spring Validation API.
The hard and fast rule is never, ever blindly accept user input. In many frameworks, Grails included, this has exposed some nasty security holes.

Related

NameError exceptions on finding matching Controller action Helper

I'm reading active_support documentation and it says that whenever there's a controller action called, rails searches for corresponding helper class. If there's no such class, an exception is thrown, caught and possibly rethrown.
I'm curious how (in)efficient is this and should I just have empty helper classes for the sake of not throwing exceptions in the background of my code?
I'm not trying to do any kind of premature optimization, I'm just looking into internals of rails and was curious as to why would they make it so that it always throws exception when there's no helper defined.
Here's the related documentation:
http://guides.rubyonrails.org/active_support_core_extensions.html#extensions-to-nameerror
Any insights and more details would be appreciated.
Thanks!
I'm going to answer from a place of "wishful thinking", not from any particular knowledge about Rails internal code. I know (and love) that Rails was built with the busy developer in mind: it was designed by someone who hates repeating himself, with an ethos of DRY code and sensible defaults in mind.
So given that, it sounds like a horrible idea to worry about setting up empty helper classes just for the sake of making the Rails startup code more efficient. That's very opposite to the intentions that Rails was built on, and I think you can count on the community holding to those intentions going forward.

print and debugging functions in rails?

In php one can print_r() anywhere in the view, controller, or model. Is there anything like that in rails? I tried to_yaml and inspect. They don't seem to print things out from the model. Is it only allowed to be used in view? If not any example in model or controller?
This doesn't really exist because it's the lest effective way of debugging.
Being able to dump output to the browser depends on where you are. It's trivially easy in views, slightly cumbersome in controllers, and too difficult to be worth-while from models.
Fortunately, there are much better tools than simply dumping things into the browser.
You can use pry to stop mid-request, open a REPL environment and interactively query or modify the state of your running application.
If you simply want to trace the flow of execution through output, use the logger:
Rails.logger.info(my_object.inspect)
Normally you'll identify problems in your model, controller or integration tests long before it becomes an issue. In that context you can use puts to output whatever you want when instrumenting bits of code and it will show up in your test output:
puts object.inspect
Within the Rails operational environment you can use Rails.logger:
Rails.logger.debug(object.inspect)
This will show up in log/development.org where you can see what's going on. It's best to leave this at debug level so it doesn't clutter up your production logs if left in by accident.
Short answer is, you can't. At least not in one line. And not only because this is a violation of MVC, there are also practical reasons that prevent this.
There is no reliable way to output a bunch of data in an arbitrary format and keep it valid. Outputting it in JSON views may easily result in invalid data. So if your debug data can only be handled by a browser, that output should only be specified in views for browsers. Even if none other exist, separate concerns.
There is a substitute, of course. Rails 4.2.0 ships an app template with web_console. All you need to start using it is add a call to console in your views somewhere, like the app's general layout file. If that's actually ERB, add this line below:
<%= console %>
And wherever it appears, you have a REPL in the context of the currently rendered view, where you can easily inspect objects and even perform actions that change your data.
There is also a variety of methods to output data into the server's console or log file. They've been listed in other answers. I'll add a little to the solution involving logger.
Rails Panel. It's a Chrome extension that adds another tab to Chrome Dev Tools (that show up behind F12) named "Rails". For it to work, you need to add a meta_request gem to your app (make sure it's in group development!). Once working, it will show loads of data about how the page was processed:
Time spent fetching data, rendering it
Parameters for the given request
Executed DB queries, duration and lines they've been triggered by
View files involved
Log entries emitted on this request and what triggered that
Errors encountered
This one and some other debugging things are discussed in this Railscast.

log an exception myself, just like Rails

If your app raises an exception not caught by your app, then Rails will log it, using it's own rules for when to log, what to log (backtrace clean), how to format the log, etc. And will then present a 500 error message.
I am rescue'ing some exceptions myself, because I can recover from them with a better user experience than a generic 500 error.
However, they still represent unexpected conditions that should not have been possible, and I still want to log them -- I want to log them just like Rails does.
One would think there would be a method in Rails I can actually call myself to do this. Alternately, if needed, if I could find where in Rails does this, I could just copy and paste duplicate the logic to do it the same way.
But I'm having trouble finding what's what in Rails regarding this stuff at all. The code is confusing, spread accross middleware as well as Rails itself, different parts that look like they're going to tell me what I need but then don't seem to, etc.
Anyone have any ideas?

Implementing a multi-parameter search service

I would like to design a search service which applies to a multiple set of different request paramaters. It could be called with one parameter only, or with more.
The problem is that some of the params could only be used solely, or are mutually exclusive with others.
Another problem is that some params are really required, while others are only optional.
The easiest way to resolve this is to involve a series of if-statements in the controller's search method, checking for the existence of some parameters or sets of parameters, and reacting correspondingly. Coming from the world of Java however, I have been taught to disbelieve anything that ends up in a bunch of if or switch statements. Back there, we often resort to factories, to which we delegate the decision to choose a proper search strategy from a bunch of strategy classes. All that was ever necessary, was to configure a proper mapping between request parameters and strategy classes.
I also know that the Rails dev mentality tends to solve about problem in a much less abstract and more business-like manner.
What is the proper way to make complex multi-parameter search service?
Rails 2: searchlogic
Rails 3: meta_search
Then it's as easy as Model.search(params[:search])
Sleep easy.

Searching sub-models with Ferret

I have a rails app in which I am trying to do some full text searching on. Ferret seems to be the most popular choice. However, I have an issue.
I have a 'thing' which contains an id which determines if a user can see it (and therefore search it), but I want to search sub-models of this 'thing' which are related to my 'thing' but don't directly contain any references back to the user.
Therefore, how do I implement it? Is there a clever way of implementing this, or do I need to dirty my models with a link to the domain identifier?
I think it would be very wrong to assume that Ferret is the most popular choice for this. Most people I know have ditched Ferret and replaced it with Sphinx. And the people who can't use Sphinx for some reason have opted for Xapian.
That said, the answer to your question is likely to be largely the same regardless of the indexing system you choose:
When you're dealing with permissions and indexing, you can't effectively index anything related to the permissions system because it's going to be user-specific. All your permissions stuff needs to live in your models/controllers somewhere. I'm fond of putting all my permissions stuff in a module and then including it in my model, so that I can easily share it between models.
Pagination can be a real pain for this kind of thing because you request 10 items from your search engine, and then your permissions code rejects 5 of those items, which means you have to keep running searches until you have your first ten items to display. And now when you want page two, well, things turn into a real mess then. Heaven forbid they decide to skip straight to page ten, because now you can't do tricks like giving a start ID instead of a page number. Really, it's not something you want to do at all if you can help it.
There really are no "clever" ways of getting around the mismatch between permissions and full-text indexing. At least, none that I know of. It's just a pain.
I suggested to my boss when we first started out that the only sane solution was an egalitarian permissions system: If we gave you a username and password, then you have access. He wasn't a fan.

Resources