I am still struggling to get my head around strong parameters and exactly how they work.
Firstly, which parameters are actually available by default (Edit: just confirmed that it seems, ID is, why is this?), or are they all considered unsafe until explicit permission?
Also how do I go about permitting a single parameter. I have a single ID parameter that I would like to permit that is not from a form, it is simply examples/:id
There are plenty of examples for multiple params eg
params.require(:available_time).permit(:time_start)
i understand that this statement is permitting time_start withing the available_time hash, but what if available time was not multidimensional and just included a value. How would I go about permitting it
would params[:available_time].require.permit or something work?
Some clarification would be great, thanks
If you just have a single parameter, you don't really need to use strong parameters. You can just use a regular hash when creating or updating your object:
def create
MyRecord.create(value: params[:value])
end
If you have more than one and this starts to get overwhelming, then it's better to use the multidimensional hash structure.
Related
I am starting a project in which I am trying to have the least possible effort in the evolution, one of the points is the strong params that must be inserted in the Controller.
With that, I created a generic method that allows all parameters, followed below:
#resource_params ||= params.require(resource_name.to_sym).permit!
The problem is this: If I want some of the model's parameters not to be used (including nested parameters) is there any way to do that other than just overriding the method and adding all the allowed parameters manually?
The application is being born in Rails 6, but the idea is some solution that theoretically serves for past and future versions.
Has anyone had the same feeling of using something that really facilitates that part of the process?
This became a problem from the moment I imagined someone passing created_at and updated_at in the parameters and changing these timestamps.
Use can use except
params.require(resource_name.to_sym).except(created_at, updated_at, ...)
I just want to know if it is safe to call params like params[:id] which come from the request parameter in url (eg. /?id=<script>console.log(1)</script>) at slim tempalate for rails like h3 = params[:id] because of security reason.
Is the params automatically escaped or sanitized?
Thanks for your help.
This really depends on context, but in general I would say rendering raw params directly in a view is an anti-pattern. Params are really the concern of the controller. I can't think of a case where you'd want to render a raw parameter in a view without some preliminary processing, validation, or sanitization.
Params (along with any other value) would be HTML sanitized in the view, although, remember, it's likely that users could provide any value they want here, so it's worth asking yourself what vulnerabilities or boundary conditions this may cause.
Finally, while this isn't an absolute rule, I'm strongly of the opinion that primary IDs should remain a concern of the database. In some cases it may be risky to expose them to the user or outside world. The reason is that you're leaking information about your database (e.g. how many records there are) if the primary key is auto-incrementing, which it usually is. In such cases it might be worth obscuring or hashing the primary key.
I'm adding strong parameters to a Rails 3.2 project. It works fine with the models I want to protect. But it seems to affect other models/controllers. For example, serialization and ransack search parameter.
It seems because strong parameters changes the class of params from HashWithIndifferentAccess to ActionController::Parameters. I wonder if there a way (or is it a good practice) to convert params back so that I can use strong parameters and don't break the current code?
So we run a code quality tool called reek once in a while as part of our project. The tool basically looks for code smells and reports them. Here, we observed that we get "Duplication" smell every time we try to access a key in params more than once (As if we are making a method-call twice with same parameters or we are duplicating an if condition etc). However, params is just a Hash, right? Other hashes don't get duplication smell when their keys are accessed more than once.
Why is this so? What are params exactly? Does it make sense to cache params in a local variable then use them? Will it help or its the same? Or is there something wrong with the tool? Help!
With the current version it's best to run Reek only on your app/models folder, because it raises false positives against views and controllers.
params is a kind of DTO (data transfer object) close to the system boundary, and so its characteristics should be different than regular code. But Reek doesn't know that (yet). I plan to improve Reek in the near future so that it plays better with Rails. For now though, your best bet is to restrict it to looking at app/models (and maybe app/helpers and lib).
params is a method call that does a #params ||= #request.params
It might be that it thinks params is a complicated method, so it wants you to try and cache it in a variable, but, dont think that would be worth it especially since it is memoized (based on my rack_process.rb from Rails 2.2)
params[:foo] is a method-call to Hash#[], so reek is correct. I'm not familiar with reek, so I can't tell why other Hash accesses don't get counted the same. Hash#[] should be fast enough that you don't need to store it in a local variable unless you're in a very performance critical part of your code.
The only difference between the params Hash and a regular Hash is that it uses with_indifferent_access, meaning you can access any key with a String or a Symbol.
I believe every time you call params, there is an initialization step which generates method calls, i suppose you can try creating a params and checking number of calls.
this could be blind guess. :-)
I'm curious about people's experiences using AR's to_xml() to build non-entity fields (as in, not an attribute of the model you are serializing, but perhaps, utilizing the attributes in the process) from a controller.
to_xml seems to supply a few options for doing this.
One is by passing in references to methods on the object being acted on: during the serialization process, these methods are invoked and their results are added to the generated document. I'd like to avoid this path because some of the generated data, while depending on the object's attributes, could be outside of the scope of the model itself -- e.g., building a URL to a particular items "show" action. Plus, it requires too much forethought. I'd like to just be able to change the resultant document by tweaking the to_xml code from the controller. I don't want the hassle of having to declare a method in the object as well.
The same goes for overriding to_xml in each object.
The other two options seem to fit the bill a little better: one is by passing in procs in the serialization options that generate these fields, and the other is by passing in a block that will yielded to after serialization the objects attributes. These provide the kind of at-the-point-of-invocation customizing that I'm looking for, and in addition, their declarations bind the scope to the controller so that they have access to the same stuff that the controller does, but these methods seem critically limited: AFAICT they contain no reference to the object being serialized. They contain references to the builder object, which, sure I guess you could parse within the block/proc and find the attributes that have already been serialized and use them, but that's a harangue, or at least uneasy and suboptimal.
Correct me if I'm wrong here, but what is the point of having procs/blocks available when serializing one or more objects if you have to access to the object itself.
Anyway, please tell me how I'm wrong, because it seems like I must be overlooking something here.
Oh and yeah, I know that I could write my own view. I'm trying to leverage respond_to and to_xml to achieve minimal extra files/lines. (Though, that is what I resorted to when I couldn't figure out how to do this with AR's serialization.)
**EDIT 3.29.09 -- I just submitted a patch for this to Rails. If you're interested, show some support :) https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/2373-record-sensitive-procs-for-to_xml
Actually the Proc is passed the same options hash (minus the procs option) you passed into to_xml. So you can pass in any extra objects the Proc needs to do it's job:
proc = Proc.new {|options| options[:builder].tag!('reverse-name', options[:object].name.reverse)}
object.to_xml :object => object, :procs => [ proc ]
Since you're getting the proc is getting the same options to_xml is, this is allows you to pass in whatever options you need.
Woo! My patch to handle this scenario was accepted: http://github.com/rails/rails/commit/c39151a84768397d3bb025c6e8f877eac59ebbf9 It's a part of ActiveModel now, and I'm not exactly sure what the release schedule for that is; I'm thinking Rails 3.