I'm writing my first mobile API an I can't find the best way to validate params, entities etc.
Now I do somethig like this before_filter :verify_adding, :only => :add and verify every param and entity in this verify methods. It doesn't look like elegant solution.
Please, suggest the best way to do such verifications
It's not the Rails way of validating input data.
Mostly you build an object using params and call the valid? function.
Because validation is a cross cutting concern which means that it will happen in different layers of your application, so it will be a good practice to put it somewhere so that you'd be able to call it somewhere else.
If your objects are ActiveRecord objects then the best place and way of validation is adding validation rules to your domain object which is an ActiveRecord derived object.
If not you can add ActiveModel modules to your domain object and use validation rules just like a regular rails app.
Related
I was wondering if there was a "proper" way to use RoR's MVC for doing all CRUD actions through something like rest_client. I won't have access to the DB but rather rest requests to do all CRUD actions.
Is there any way to define a model that contains all of the json data that would be returned on a get and put that into a model that can use Model.Save, Model.Create etc like a regular RoR application?
Would creating new methods def save, def create inside the ApplicationController work for this or not?
Edit: rest_client isn't required, just the ability to send json in post, get, delete and put with basic auth at the same time.
Edit 2: The only other idea I had was to use Active Model but those don't have save, delete etc methods. Would creating those that somehow tie into the ActionController::Base for wiring do this or not?
take a look at activeresource http://api.rubyonrails.org/classes/ActiveResource/Base.html
I am building an API using rails that can take quite a few parameters. Ideally, if the user includes an extra, unnecessary paramater in the request by accident which does not make the request ambiguous I would like to process it as normal. This obviously prevents me from simply writing
ApiRequest.new(params)
since an UnknownAttributeError will be thrown if there is anything extra in the params hash. Is there a simple way of rejecting the extra attributes or will I have to write a method to manually validate the request before creating a new object. Also, would this be considered bad practise for an API, should I be responding with HTTP 400 if this occurs?
Thanks,
Tom
Thanks for the suggestion Sergio, I ended up adding the following initialize method in my ApiRequest class which allows me to mass assign regardless of what is in the hash. If anyone uses this just make sure you ensure attributes are attr_protected if they need to be.
def initialize(params)
params.delete_if {|k| !self.respond_to? "#{k}="}
super
end
So I'm writing a Facebook clone for a school project using Rails and I need some way to keep track of which users are logged in. At the moment, I'm a bit time-pressed, so I decided just to update the User model every time they visit a page with a last_seen attribute.
Problem is, the user model requires revalidation to successfully update_attributes. So I'm wondering two things:
Is there a better way to do this that I'm missing?
If not (or if it would take too long) is there a way to bypass the validation?
to 1.: I cant give you an exact answer but I think itwould be better to deal with this problem using a javascript on the clientside with a timer that sends an ajax request all xxx secounds and an action that receives this requests and saves it in a seperate table associated with the User.
to 2.: Yes there are some ways to bypass validations The most pragmatic way is to bypass the :validate => false option when saving the object but then you can use update_attributes:
object.save(:validate => false)
So there is also the possibility to use conditional validations that are only used when a specific condition is complyed. There is a railscast about that => http://railscasts.com/episodes/41-conditional-validations .
I am new to RoR and started working on a typical 'has_many' association (ie. a user has many friends). I have everything working correctly, but I don't like having the ids exposed in the url. I find that I need to add extra validation in my controller to make sure the ids represent valid associations in case the user manually entered different ids.
Personally I would like to see the ids out of the url and passed via some other means but that is not always possible. Shallow nesting of resources will help reduce the number of ids I need to validate at least.
What is the RoR philosophy on this? I have not seen anything specific to this issue.
Thanks
the URL has parameters if it is a GET url.
Try using POST parameters, which means your url will no longer be cluttered. Note that a malicious user can still send a made-up POST request using curl.
My approach to this is implementing proper authorization. If the user requests information for an object he is not permitted to read, this should be handled by an authorization framework.
With CanCan or Declarative Authorization you can define rules that replace your "manual" (and error-prone) checks in controllers.
I like the IDs being in the URL. That is what REST is about. Getting information for specific Resources, which have to be identified with an ID.
You can use Friendly ID in order to replace the integer ID by a slug (e.g. users/tollbooth instead of users/42).
basically ror routes by default takes id as key to generate urls. If you are not fan of id based urls then you can always override urls by using to_param inside model.
def to_param
# make sure this field is always present & unique
username
end
then by default you will start seeing username instead of id inside urls
How to find object inside controller actions
User.find_by_username(params[:id])
If you dont want to do this manually make use of slug gems like friendly id
My Rails application has a number of forms. When Joe uses my app, I want each form to provide him with immediate visual feedback as to the validity of his input for each field. One field checks the format of his email address - pretty simple. But another allows him to associate the current resource with a number of other resources, and complex business rules apply. If the form is incomplete or invalid, I want to prevent Joe from moving forward by, for example, disabling the 'submit' button.
I could duplicate the validations that appear in my Rails code by writing JavaScript that does the validation in the browser as well. But this smells bad - any time business rules change, I'll need to update them in two places with two different languages and two sets of tests.
Or I could add a single method to the controller for the resource called 'validate'. It would accept form data in an AJAX request, and return a response that could then be used inside Joe's form to provide real-time validation feedback. Unlike the 'create' action, the 'validate' action would not change the state of the server. The only purpose of 'validate' would be to provide a validation response.
The dilemma is that I don't like adding actions to RESTful controllers in Rails. But I like even less the idea of duplicating validation code in two different contexts.
I noticed this SO question, which touches on this subject. But I'm not interested in a plugin or piece of technology. Nor do I consider this question necessarily Rails-specific. I'm more interested in how best to handle this kind of problem in general in a Web application.
I also notice this SO question, which doesn't include the constraint of maintaining a RESTful architecture.
Given the need to dynamically validate form data with complex business rules in a Web application, and the desirability of maintaining a REST-like server architecture, what is the cleanest, most maintainable way to accomplish both at the same time?
I see no problem in creating a validator "processing resource" that can accept an entity and ensure that it passes all validation rules.
You could do this either with a global validator
POST /validator
where the validator will have to identify the passed representation and perform the appropriate rules, or you could create subresources,
POST/foo/validator
As long as these urls are discovered via hypermedia and the complete representation to validate is passed as a body of the request, I see no REST constraints being violated.
I hope I understood correctly, but you could send the javascript requests to the same create action. For example:
def create
#data = DataObject.new(params[:data])
if request.xhr?
response = #data.valid? ? { :success => true } : { :errors => #data.errors }
render :json => response
return
end
# #data.save etc..
end
I'm actually using something like this in a multistep wizard (one page form, with hidden css sections).
You are right not to duplicate validation logic on client (javascript) and server side). But adding validation resources also adds maintenance effort and costs server network calls. I like to do basic validation on client side (better user experience) and for data consistency on server side also.
Why don't you attach your model with validation metadata and then the forms + javascript for validation gets generated. On the final submit you also do a final validation on server side based on the model.
I am sure some generic validation logic is possible with Ruby. I guess also some existing validation frameworks could be reused.