Save input value while field is disabled - ruby-on-rails

How do you save an input value, with input field disabled, although you have specified a value?
The value for #vat_rate is not being saved:
<%= f.text_field :vat, value: #vat_rate, disabled: true %>
If disabled is set to false, then the value gets saved to the :vat column. Why?
A company is registered for vat at 20% so they are not allowed to change it without approval. On their invoice form, the 20% is displayed and cant be edited. That's how I want it. I want the field to be disabled while making the 20% visible.

I'm just going to complete #Vasfed's answer: disabled fields are not sent to the browser. You could use a hidden field, but please don't (again, see #Vasfed's answer).
To store a value in the session in Rails, you can just set it to session[:key] = 20, but it might not be the best idea: you could just re-compute it, or re-fetch it from the DB when you need it.

Do not trust data from the clientside, user may alter your page and gain something from setting other values.
You can for example pass value in session, or via some other way - calculate/fetch it again in create/update action.

Related

Is it a security issue to assign a role in a form hidden_field at sign-up?

I have a sign-up form with an email field and a hidden field assigning a role to the User.
<%= f.hidden_field :role, options = {value: 'standard'} %>
The form is accessible to everyone, and assigns an "author" role.
I'm wondering if it is a secure way to assign role since the hidden field is visible in html.
Any help is welcome. Thank you in advance.
Note that I do auto-assign a "reader" value to the User.role.
A hidden field in a form is no more or less secure than any other data that come from user. That is, it should not be trivally trusted: It comes from the user and is open to manipulation and specialty injection.
When the data is sent back to the server, the server should validate that data and not assume that the operation is allowed/invalid just based on a particular user-modifiable context. Depending upon needs, approaches like hash checksums can be used to have a very high degree of confidence that the data was not tampered with (but again, this should be verified by the server each request!). Using "session state" mitigates the problem entirely by keeping the data out of user-manipulation land.

How to update certain parts of a form

I'm looking to create a report with similar that has a checkbox next to each row. Each row has some fields that are editable (such as comments). What I'd like is to give the user the ability to check off which rows he/she would like to update by selecting the checkbox next to that row. Then I'd have a save button at the bottom of the form that only updates the rows that have a check box active next to it.
I'm pretty new to rails and web programming in general so any advice/direction you might be able to give me should prove helpful.
A popular way to achieve this is to :
1- All your checkboxes should share the same name.
2- All your checkboxes' values should be the ID of the row/object
3- When you POST the form, only the checked checkboxes are in the POST data. Retrieve those IDS and only update these objects.
For example, your checkbox should be something like :
<%= check_box_tag "row_ids[]", row.id, false, :id => "row_#{row.id}" %>
Then, in your controller :
Row.find(params[:row_ids]).each do |row|
# do whatever you want
end
Well you can do this, but it adds more work for the user: they have to check off multiple checkboxes before hitting Update. It be nicer if they just hit Update and it worked.
The basic idea is you want the user to just click Update and your code only updates records that changed.
What you can do is store (in a hidden field tag) the ID of each row's record. Then when you update, you loop through all rows and you grab (based on the ID stored in the hidden field) the record from the database. Let's say only Comments were editable. Then you can check to see if the comments have actually been changed (like with a simple string comparison) and if they have, update it. If more things are editable, then you can check them too before deciding if you need to update or not.
That is a high level description, but let me know if you want some more implementation details.

How to give user live feedback for Rails form

I need to make a Rails form that responds back to the user live as they input fields.
Specifically, the user will need to input four decimal fields representing data from some tests our company runs. The problem is that the testers often input incorrectly (leave out a digit, or hit a '4' instead of a '1', etc).
This is easy to check, as in real life, the inputs shouldn't vary by more than 5. I would just like to send a live message back as they input saying something like "Please double check there is no mistake in your input" if the fields vary by certain conditions.
I looked at many live validations tutorials, including the one in Advanced Rails Recipes, but a) i don't need a server request for this, and b) this is not technically a validation since I only want to warn the user of the input, not prevent them from making it.
You can do this with some javascript by attaching onchange to the input fields that you want to warn users for as they're filling out the form. This way, as they move to the next field in the form, your event handler gets called, checks the value of the form field they just inputed information for, and decides whether or not to alert the user with a warning message. You wouldn't have to hit the server at all.
An example using jQuery:
$('#your_form_field').change(function () {
var isValid = false; // Validate the input's value based on some criteria
if (!isValid) {
alert("Please check your work.");
}
});
AJAX with RJS RailsCast could help. You could write RJS that is returned once from server and then executed N times on events on the client.

Rails - Should an object's types be in its own model?

I have a contact, and contact has_many :phones. The phones table has a column named, phones_desc, where I want to include the type of phone number the user has saved.
My question / Best practice
Should I provide a select with manually provided options (such as "mobile", "work", "home")...
-or-
...create a new model named phones_types where I can add the values I'd like, thus creating a unique ID for each one. Then I can do the following after changing phone_desc to phone_type_id, adding phones has_many :phone_types and giving the phone_types table a name column:
#phone = Phone.first
#phone.type.name
Sidenote
I'm currently doing it with the first option (not a separate model) and am having trouble with it selecting the value when I go to edit the parent object. In other words, the select options don't have the saved value selected when going to edit phone numbers.
It always has the first option selected, so the user may inadvertently change the phone_desc without realizing it.
If the first option is in fact the better way to go, would you have any insight on how to get the objects value to be the selected value when editing phones descriptions via a select?
I'd still go for a separate model for the phone type. This way, you can more easily add other phone types later on. Also think about i18n, it might save you some headache when translating "Mobile" to Japanese.
Turns out that option one works just fine, and I can get the selected option to work too. It was a problem in the order that I supposed the option parameters.
I changed:
<%= f.select :number_desc, '<option value="mobile">Mobile</option><option value="work">Work</option><option value="home">Home</option><option value="other">Other</option' %>
to:
<%= f.select :number_desc, [["Mobile", "mobile"], ["Work", "work"], ["Home", "home"], ["Other", "other"]] %>
And voila - selected works fine. :)

Retrieve all options from select tag after submitting

I have a slight problem with getting the options within the select tag. Some background information; This is a report, and as such the select options will vary depending on what is stored on the DB depending on some conditions. So, I'm using observe field to get the selected option, BUT, I need to get all the options because I want render that same report with a) the selected option that was chosen the first time and the remaining ones.
select "price", "desc", #desc, {:prompt => 'All'}
I'm obviously observing the field, to display the result, so the variable #desc is the hash with the all the values.
Can you help me get hash to be sent to the controller, and how can I have the selected option selected in the hash to be sent back to the view....
Cheers
You have the options already, so where'd you get them? Are they report specific? If so, send the report_id back so you can look all of them up again, then you can select the selected one.
You can't (easily) get all of the options in a select list. Technically, you could write a javascript function that would grab all of them and send them as parameters. Or, you could write them out as a hidden field and submit that with the request, but both of those ways are ugly.

Resources