Passing Custom Form Values to a Custom Controller Action - ruby-on-rails

In Rails, I have a custom controller action that needs to accept some parameters from a form:
def update_ordid
# Get the active exchange
#exchange = Exchange.find(params[:id])
# Decide which order ID field to update
active_order_field = params[:ordfld]
# Save the order ID
order_id = params[:ordid]
if active_order_field == 1 then
#exchange.order_id_1 = order_id
else
#exchange.order_id_2 = order_id
end
#active_exchange.save
respond_with(#exchange)
end
Because these parameters aren't actual data fields in the exchange table, I would typically invoke the action by using a link such as:
link_to "Update Order ID", update_ordid_exchange(ordfld: value_from_form, ordid: value_from_form), :method => :post
Because in this case the value of these parameters needs to be populated by user input, I created the following form to pass the data:
<%= form_for(#exchange, url: update_ordid_exchange_path) do |f| %>
<div class="field">
<%= f.label :ordid, "Order ID" %><br>
<%= f.text_field :ordid, class: "form-control" %>
</div>
<% if #isrequestor == true %>
<%f.hidden_field :ordfld, :value => "1" %>
<% else %>
<%f.hidden_field :ordfld, :value => "2" %>
<% end %>
<div class="actions">
<%= f.submit "Submit", class: "btn btn-primary" %>
</div>
<% end %>
When I attempt to render this form, I receive the error: undefined method `ordid' for #
When researching this issue, I found that I could be able to do this by changing the text_field line to:
<%= f.text_field_tag :ordid, class: "form-control" %>
While this resolves the initial error, it throws a new error: undefined method `text_field_tag' for #
Any ideas as to what I'm doing wrong?

You cannot use form_for since your form elements doesn't represent the attributes of a model. use form_tag instead
<%= form_tag(update_ordid_exchange_path, :method => :patch) do%>
<div class="field">
<%= label_tag "Order ID" %><br>
<%= text_field_tag :ordid, class: "form-control" %>
</div>
<% if #isrequestor == true %>
<%= hidden_field_tag :ordfld, "1" %>
<% else %>
<%= hidden_field_tag :ordfld, "2" %>
<% end %>
<div class="actions">
<%= submit_tag "Submit", class: "btn btn-primary" %>
</div>
<%end%>
Documentation here
form_tag vs form_for
hidden_field_tag

I'm a bit new to this myself, but I believe it's because you're calling "text_field_tag" from a form_for instead of form_tag builder object. Try just leaving off the form for object as such:
<%= text_field_tag :ordid, class: "form-control" %>

Related

Rails - Save parameters between actions

I have an app that books spaces for certain dates. In the index page, I have a search form to display only the spaces that are available from params[:query1] to params[:query2] certain dates. Then in the space show page, I have a form for booking the space.
I'd like to maintain the params[:query1] and params[:query2] also in the space show page as the default value for the booking form.
index.html.erb:
<%= form_tag spaces_path, method: :get, class: "form-inline" do %>
<%= label_tag :query1, "Check in" %>
<%= date_field_tag :query1, params[:query1], class: "form-control" %>
<%= label_tag :query2, "Check out" %>
<%= date_field_tag :query2, params[:query2], class: "form-control" %>
<%= submit_tag "Search", class: "btn" %>
<% end %>
show.html.erb
<%= form_with(model: [#space, #booking], local: true) do |f| %>
<%= label_tag :check_in, "Check in" %>
<%= f.date_field :check_in, value: params[:query1], class: "form-control" %>
<%= label_tag :check_out, "Check out" %>
<%= f.date_field :check_out, value: params[:query2], class: "form-control" %>
<%= submit_tag "Reserve", class: "btn" %>
<% end %>
You can use a session to store your queries and use them throughout your app. You can store your queries in a session in your index action like this:
def index
session[:query1] = params[:query1]
session[:query2] = params[:query2]
end
Then in your show action, you can access the session like this:
def show
#query1 = session[:query1]
#query2 = session[:query2]
end
In your form on your show page, you can then use the instance variables:
<%= form_with(model: [#space, #booking], local: true) do |f| %>
<%= label_tag :check_in, "Check in" %>
<%= f.date_field :check_in, value: #query1, class: "form-control" %>
<%= label_tag :check_out, "Check out" %>
<%= f.date_field :check_out, value: #query2, class: "form-control" %>
<%= submit_tag "Reserve", class: "btn" %>
<% end %>
Learn more about session

Getting undefined method `[]' for nil:NilClass even when the instance variable is defined

I am trying to call a controller action at two different places.
The controller is as follows:
def create
#phone_number = PhoneNumber.find_or_create_by(phone_number: params[:phone_number][:phone_number])
#phone_number.generate_pin
#phone_number.send_pin
respond_to do |format|
format.js # render app/views/phone_numbers/create.js.erb
end
end
I am trying to call create on a link in view:
<%=link_to "Resend Pin", phone_numbers_path, method: :post %>
My rake routes output looks like this:
phone_numbers POST /phone_numbers(.:format) phone_numbers#create
new_phone_number GET /phone_numbers/new(.:format) phone_numbers#new
phone_numbers_verify POST /phone_numbers/verify(.:format) phone_numbers#verify
I have data in PhoneNumber activerecord. When I click on "Resend Pin" I am getting following error:
NoMethodError in PhoneNumbersController#create
undefined method[]' for nil:NilClass`
Can somebody please tell me what am I missing here ?
html.erb
<div id="send-pin">
<h3>What's your phone number?</h3>
<%= form_for #phone_number, remote: true do |f| %>
<div class="form-group">
<%= f.text_field :phone_number %>
</div>
<%= f.submit "Send PIN", class: "btn btn-primary", id: 'send-pin-link' %>
<% end %>
</div>
<div id="verify-pin">
<h3>Enter your PIN</h3>
<%= form_tag phone_numbers_verify_path, remote: true do |f| %>
<%= hidden_field_tag 'hidden_phone_number', '' %>
<div class="form-group">
<%= text_field_tag :pin %>
</div>
<%= submit_tag "Verify PIN", class: "btn btn-primary" %>
<% end %>
<%=link_to "Resend Pin", phone_numbers_path, method: :post %>
</div>
params[:phone_number][:phone_number] is null.
Try the below in view
<div id="send-pin">
<h3>What's your phone number?</h3>
<%= form_for #phone_number, remote: true, html: {id: "first_form"} do |f| %>
<div class="form-group">
<%= f.text_field :phone_number %>
</div>
<%= f.submit "Send PIN", class: "btn btn-primary", id: 'send-pin-link' %>
<% end %>
</div>
<div id="verify-pin">
<h3>Enter your PIN</h3>
<%= form_tag phone_numbers_verify_path, remote: true do |f| %>
<%= hidden_field_tag 'hidden_phone_number', '' %>
<div class="form-group">
<%= text_field_tag :pin %>
</div>
<%= submit_tag "Verify PIN", class: "btn btn-primary" %>
<% end %>
<%=link_to "Resend Pin",'#', id: "resend_pin_code" %>
</div>
<div id="status-box" class="alert alert-success">
<p id="status-message">Status: Haven’t done anything yet</p>
</div>
<script>
$("#resend_pin_code").click(function(){
$("#first_form").submit();
}
)
</script>

Undefined Local Variable or Method `f' In a view partial

This seems like such a stupid, easy fix (it probably is) but I've been searching SO and other areas on the web with no luck. I'm getting an undefined method local variable error 'f' within my partial used in my view. I'm assuming that the "do block" is ending somehow prior to reaching the partial but I'm not 100% certain.
Partial
<% if user_admin_or_premium? %>
<div class="form-group">
<%= f.label :private, class: 'checkbox' do %>
<%= f.check_box :private, :true %> Private Wiki?
<% end %>
</div>
<% end %>
View
<div class="col-md-8">
<%= form_for #wiki do |f| %>
<div class="form-group">
<%= f.label :title %>
<%= f.text_field :title, class: 'form-control', placeholder: "Enter Wiki Title" %>
</div>
<div class="form-group">
<%= f.label :body %>
<%= f.text_area :body, rows: 10, class: 'form-control', placeholder: "Enter Wiki Body" %>
</div>
<%= render partial: "wikis/form", f: f %>
<div class="form-group">
<%= f.submit "Save", class: 'btn btn-success' %>
</div>
<% end %>
</div>
Full Error
NameError in Wikis#new
undefined local variable or method `f'
<% if user_admin_or_premium? %>
<div class="form-group">
<%= f.label :private, class: 'checkbox' do %>
<%= f.check_box :private, :true %> Private Wiki?
<% end %>
</div>
Omit the partial: key from your render function:
<%= render "wikis/form", f: f %>
Easy fix, but certainly not obvious, I've been stumped by the same issue before. The above statement is equivalent to the following:
<%= render partial: "wikis/form", locals: { f: f } %>

Using placeholder in a update form

I want to replace the default value of a text_field in a update form by a placeholder. How can I do that ?
My first thought was the following code but the default value of the text_field is still here :
<%= form_for(some) do |f| %>
<div><%= f.text_field :thing, placeholder: "what an example !" %></div>
<%= f.submit %>
<% end %>
You can use text_field_tag
<%= form_for(some) do |f| %>
<div>
<%= text_field_tag "some_thing", (some.thing unless some.thing=="default value"), :name=> "some[thing]", :placeholder => "what an example !" %>
</div>
<%= f.submit %>
<% end %>
Hope, it will work..
Thanks

Rails 3 - keep params after submit

I want to keep my params afterr i do submit.
In my Rails 3.2.0 application i have something like that:
http://0.0.0.0:3000/journals?class_code=11v&subject_name=Math
And i have form:
<%= form_for #lesson, :html => {:class => "form-horizontal"} do |f| %>
<%= field_set_tag do %>
....
<%= f.submit "Create", :class => "btn btn-large btn-success" %>
<% end %>
<% end %>
I want to keep my params (class_code and subject_name) after f.submit. How can i do that?
To store all parameters in one field, you could use:
<%= hidden_field_tag :parameters, request.query_string %>
And then you can access them in controller, using:
parameters = parse_nested_query(params[:parameters])
hidden fields
....
<%= hidden_field_tag :class_code, params[:class_code] %>
<%= hidden_field_tag :subject_name, params[:subject_code] %>
<%= f.submit "Create", :class => "btn btn-large btn-success" %>
<% end %>
but - if those are attributes of your model, then assign them in the new action of the controller
def new
#lesson = Lesson.new(:class_code => params[:class_code], :subject_code => params[:subject_code])
end
# in this case the view code is slightly different
<%= f.hidden_field :class_code %>
<%= f.hidden_field :subject_code %>

Resources