Passing arbitrary text value to ruby controller action - ruby-on-rails

I know this is answered elsewhere, but I was looking and couldn't find what I needed.
I'm passing a value to a method that adds a value to a numeric attribute in the object.
I have a form, but I can't figure out how to give a textbox an arbitrary name and reference it in the view. If I pass the textbox an arbitrary symbol, it looks for that attribute in the object. I just need to name the textbox something random, and have the value pass to the controller action. The textbox value should not be connected to anything on the object, any help?
The controller action (does nothing right now, waiting to figure out how to pass values):
def addto(valu)
end
The view form:
<%= form_for(#cooler) do |f| %>
<div class="field">
<%= f.label "Increase/subtract from value:" %><br />
<%= f.text_field :dfdf%>
</div>
<p style="float:left;"><%= button_to "+", coolers_addto_path(:valu => 2)%></p>
<% end %>

You can use parameters in controller, like this:
def addto
# Here you can access your value with params[:val]
end

Related

Rails Strong Parameters: How to accept both model and non-model attributes?

I have a form to create a user model with all its usual attributes, but I am also passing a lot of non-model attributes that based on which I will create further stuff in my controller action.
My question is how I can tell Strong Parameters to accept both the user data, AND this other data that is not related to the user db wise?
To illustrate, my form could like this (submit button deleted for brievity):
<%= form_for #user do |f| %>
<%= f.text_field 'attribute1' %>
<%= f.text_field 'attribute2' %>
<%= f.text_field 'attribute3' %>
<%= text_field_tag 'attribute_not_on_user_model1' %>
<%= text_field_tag 'attribute_not_on_user_model2' %>
<% end %>
How can I use strong parameters to do this? I tried this:
params.require(:user).permit(:attribute1, :attribute2 , :attribute3, :attribute_not_on_user_model1,
attribute_not_on_user_model2)
And also this:
params.require(:user).permit(:attribute1, :attribute2 ,
:attribute3).require(:attribute_not_on_user_model1,
attribute_not_on_user_model2)
Both did not work. I am aware that I could do attr_accessor in the user, but I have a growing list of attributes in this form that are not related to the user model per se (but are nonetheless essential to the creation of the user model and its subsequent related models). We could debate that this is not the best way to do this (A form object comes to mind), but for the moment I want to see if Strong Parameters can help me here.
user model attributes are stored inside the :user hash, whereas the non-user attributes are accessible directly at the params level.
If you inspect your params Hash, you will notice that it is constructed in the following way
{ user: { attribute1: "value", attribute2: value, ... }, attribute_not_on_user_model1: "value", attribute_not_on_user_model2: "value" }
Consequently, the call
params.require(:user)
will automatically ignore any other param that is not part of the user node. If you want to include also the other params, you either compose the hash, or update the view to inject the params in the form.
Injecting the parameter on the form will cause the params to be part of the same :user node. This approach normally works very well with virtual attributes (despite the concepts are not linked each other).
<%= form_for #user do |f| %>
<%= f.text_field 'attribute1' %>
<%= f.text_field 'attribute2' %>
<%= f.text_field 'attribute3' %>
<%= text_field_tag 'user[attribute_not_on_user_model1]' %>
<%= text_field_tag 'user[attribute_not_on_user_model2]' %>
<% end %>
The other solution would be something like
def some_params
hash = {}
hash.merge! params.require(:user).slice(:attribute1, :attribute2, :attribute3)
hash.merge! params.slice(:attribute_not_on_user_model1,
attribute_not_on_user_model2)
hash
end
The solution, however, really depends on how you will user those params later. If all these params are sent as a single Hash, then you may want to compose the single hash, but in that case you may also want virtual attributes.
The point is that, without a real use case, the question itself is quite non-sense. StrongParameters is designed to filter a group of parameters passed to a bulk-create or bulk-update action. Generally, this means you have a model.
If you design a custom method, or if you have non-model methods, StrongParameters whitelisting may not have any sense, given you have control over the method you are writing and invoking.
There are many ways to do this and one way is with accecpts_nested_attributes_for: http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

What is the correct syntax for params?

According to this rails guide it is acceptable to key params with the name you associate with the html values in your template,
"When the form is submitted, the name will be passed along with the form data, and will make its way to the params hash in the controller with the value entered by the user for that field. For example, if the form contains <%= text_field_tag(:query) %>, then you would be able to get the value of this field in the controller with params[:query]"
However, when I attempt to access a param I submitted it throws the following error:
I understand that there are other params besides :name but I am just trying to get this one handled for now before passing the others. I am just making this app to practice the fundamentals.
Also, how come my params are being passed in my URL? These are forms, shouldn't they be submitted as a POST request and thereby able to use strong params with? I think the reason i'm having so much trouble is because I am used to strong params, I am unfamiliar with this syntax. Any help is appreciated, thanks!
Here is my code:
Controller:
class OrdersController < ApplicationController
def create
Order.create(params[:name])
end
end
View
<h1> Input information </h1>
<%= form_tag("/order",method: "get") %>
<%= label_tag(:name, "Enter name") %>
<%= text_field_tag(:name) %>
<%= label_tag(:email, "enter email") %>
<%= text_field_tag(:email) %>
<h2> Select color </h2>
<%= label_tag(:red,"red") %>
<%= check_box_tag(:red) %>
<%= label_tag(:green,"green") %>
<%= check_box_tag(:green) %>
<%= label_tag(:indigo,"Indigo") %>
<%= check_box_tag(:indigo) %>
<%= submit_tag("submit") %>
You need to provide a hash argument to create. How will Order know that you are setting name? You are basically doing this:
Order.create('phoot')
You need to specify what phoot is:
Order.create(name: params[:name])
# ends up being Order.create(name: 'phoot')

What is the purpose of the 'hidden_field'?

For example here's a snippit:
<%= form_for [#event, #event.comments.new], html: {class: 'form-horizontal', role: 'form'}, remote: true do |f| %>
<div><%= f.hidden_field :user_id, value: current_user.id %></div>
<div class="form-group">
What is the purpose of the f.hidden_field :user_id, ? Would the code work without it, or is it a necessity to include this line.
Cheers!
Without seeing the controller code which would process the form, the hidden field seems to be holding the id of the user currently logged in. I assume this would be used in further actions, for example, to attribute the event/comment being created against that user.
The view doesn't need the hidden field, but I would imagine the following controller action would fail if it were removed.
The hidden_field method simply creates <input ... type="hidden" /> in the html which means the value is included in the form parameters when the form submits, but the value is not visible to the user.
In Your Case,you are creating an Event with Comments for a particular User.So the user_id is passed as a hidden_field.Without it the value for user_id will be saved as nil,which would resulting an Error.

Pass data between two controllers but not via url as params

below is my code
<% if #user.empty? == true %>
<p> Sorry no data to display</p>
<%else%>
<% #user.each do |n|%>
User id = <%=n.id%> <br \>
User type = <%=n.type%> <br \>
User name = <%= n.name%> <br \>
<%= link_to "Good. You can proceed on creating a new", new_user_product_path(current_user)%>
<%end%>
<%end%>
This code is currently under searches#index. Now as you can see, after a set of results is shown, I want the user to be able to create a new product. But when creating the product, I want to make sure <%= n.name%> is pass over to new_user_product_path(current_user) (its a form). But not via url.
The form field which i want to populate is
<%= f.hidden_field :user_name%>
So, how do I do it?
Thanks
I think i found a solution
I just made <%=n.name%> to <% $name = n.name %> and since a global variable, its accessible now.
You don't need to pass name from search index, as you have current user reference:
<%= f.hidden_field :user_name, current_user.name %>
This will render a hidden input with a value of current user name.
Even you don't need this parameter to be passed after user submits form.
If you are doing this I suppose is to have the user name reference available in client, to do something like this in Javascript:
alert($('[ name = user_name ]').val());

Erroneous value for commit options in params hash

I'm using a submit_tag form helper in one of my apps. The value of this submit button should change dynamically. The two possible values for this submit button are Save and Update. So, in the view, I have done something like the following:
<% temp = 0 %>
<% text = '' %>
<% temp = ActivityLog.find_by_sql("SELECT COUNT(id) AS cnt FROM logs WHERE id > 0")%>
<% text = temp[0][:count].to_i > 0 ? 'Update' : 'Save' %>
<!-- other html contents -->
<%= submit_tag text, :id=>"submitBtn"+i.to_s, :onclick=>"submit_button_clicked(this)"%>
Now, when I run the view inside a browser, I can see the desired effect. But the rails controller receives the erroneous value for the commit options in the params hash.
For instance, when the value of text is evaluated to Save, I get the following in the Firebug:
<input type="submit" value="Save" style="" onclick="submit_button_clicked(this)" name="commit" id="submitBtn3">
But raise params.inspect in the associated controller shows the follwing:
{"commit"=>"Update",
"authenticity_token"=>"",
"time"=>{"292"=>"3.0",
"2"=>"1.0",
"456"=>"4.0"},
"date"=>"2011-09-20"}
See, although the value of the Submit button is shown as Save in the HTML, the rails controller shows the value of commit as Update. What's wrong in here?
If you are using Rails helpers, it provides a simple way to choose text on button with according to type of form:
<%= form_for #activity do |f| %>
<%= f.label :title %>:
<%= f.text_field :title %><br />
<%= f.submit %>
<% end %>
When no value is given, it checks if the object is a new resource or not to create the proper label. In the example above, if #activity is a new record, it will use "Create Activity" as submit button label, otherwise, it uses "Update Activity".
P.S. please do not use SQL in your views

Resources