Rails and Postgres array columns - ruby-on-rails

I have a model with an array column (box_ids). In my view I would like to have a field for each of the values in the array and three extra empty fields to be able to add new values to the array. How to go about this? I have the following:
<%= f.fields_for "box_ids[]", #shop do |bid| %>
<div class="form-group">
<%= bid.label :box_id %> Box ID: <%= bid.text_field [WHAT HERE] %>
</div>
<% end %>
I don't know if this is the right approach but in any case I have no method to supply to text_field.
Any suggestions?
Edit:
This works:
<% #shop.box_ids.each do |bid| %>
<div class="form-group">
<%= label_tag :box_id %> Box ID: <%= text_field_tag "box_ids[]", bid %>
</div>
<% end %>
<% 3.times do %>
<div class="form-group">
<%= label_tag :box_id %> Box ID: <%= text_field_tag "box_ids[]" %>
</div>
<% end %>
But that requires special handling in the controller - I would like to avoid that if possible.

<%= f.fields_for "box_ids[]", #shop do |bid| %>
<div class="form-group">
<%= bid.label :box_id %> Box ID: <%= bid.text_field :box_ids %>
</div>
<% end %>

Related

setting a select tag on Ruby on Rails

<%= form_tag("/posts/create") do %>
<div class="form">
<div class="form-body">
<% #post.errors.full_messages.each do |message| %>
<div class="form-error">
<%= message %>
</div>
<% end %>
<div class="continent">
<label>continent<br>
<%= #post.continent %>
<%= select :continent,
[["Africa","AF"],["North America","NA"],["Oceania","OC"],["Asia","AS"],["Europe","EU"],["South America","SA"]],
:prompt => "Select" %>
</label>
</div>
<div class="country">
<label>country<br>
<%= #post.country %>
<%= select :country,
[["Japan","JP"],["China","CH"]],
:prompt => "Select" %>
</label>
</div>
<div class="title">
<label>title<br>
<textarea name="title"><%= #post.title %></textarea>
</label>
</div>
<input type="submit" value="POST">
</div>
</div>
<% end %>
I want to set a select tag for choosing user's continent and country in the form
But It doesn't work well
I've tried some way to solve this problem.
And I just got the shape which is like "Select tag" but it's only included "prompt"
Please give me some advice.
FormOptionsHelper`s select takes these args
select(object, method, choices = nil, options = {}, html_options = {}, &block)
Try explicit putting options like this:
select :post, :country, [["Japan","JP"],["China","CH"]], { :prompt => "Select" }, { other_html_options }
If you are in a form context make this
<%= form_tag("/posts/create") do |form| %>
<%= form.select :country, [["Japan","JP"],["China","CH"]], { :prompt => "Select" }, { other_html_options } %>
<% end %>
First start off by creating the correct routes:
resources :posts
In Rails you create a resource by sending a POST request to the collection path ('/posts').
Then create the form with form_for(#post) or form_with(model: #post) (Rails 5.1+) and bind the model instance to the form builder.
<%= form_for(#post) do |f| %>
<div class="form">
<div class="form-body">
<% f.object.errors.full_messages.each do |message| %>
<div class="form-error">
<%= message %>
</div>
<% end %>
<div class="continent">
<%= f.label :continent do %>
<%= f.select :continent,
[["Africa","AF"],["North America","NA"],["Oceania","OC"],["Asia","AS"],["Europe","EU"],["South America","SA"]],
prompt: "Select" %>
<% end %>
</div>
<div class="country">
<%= f.label :country do %>
<%= f.select :country,
[["Japan","JP"],["China","CH"]],
:prompt => "Select" %>
<% end %>
</div>
<div class="title">
<%= f.label :title do %>
<%= f.text_area_field :title %>
</div>
<%= f.submit %>
</div>
</div>
<% end %>
This lets you reuse the same form for updating the resource. Also when you use the input helpers rails will properly name the inputs so that you can whitelist them with:
params.require(:post).permit(:continent, :country, :title)

Submitting two forms in Rails sharing a same param

I have a form like that:
<%= form_for #report do |f| %>
<div class="row">
<div class="col-sm-9">
<h3 class="page-header">
Children
</h3>
<div class="row">
<% students.each do |student| %>
<div class="col-xs-4 col-md-2">
<div class="std_container">
<%= check_box_tag "student_ids[]", student.id, nil, {id: "check_#{student.id}", class: "student_check"} %>
<%= label_tag "check_#{student.id}" do %>
<div class="std_label"><%= student.name %></div>
<div class="std_img thumbnail"><img src="http://www.codeproject.com/KB/GDI-plus/ImageProcessing2/img.jpg" alt=""></div>
<% end %>
</div>
</div>
<% end %>
</div>
</div>
<%= render "form_categories", f: f, report_notes: #report.report_notes %>
<%= render "messages/form", ????? %>
</div>
</div>
</div>
<% end %>
And I need to render these two partials on the bottom. The 'messages' partial is a form that responds to a different controller but needs to use the "student_ids[]" parameter present on the #report form together with its own parameters. This partial is:
<%= form_for #message do |f| %>
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<%= f.hidden_field :professor_id, :value => current_user.professor.id %>
<%= f.label :text, "Texto" %>
<%= f.text_area :text %>
<%= f.submit "Enviar", class: "btn btn-default" %>
</div>
</div>
<% end %>
How do build this "messages" partial in a way that I can use the "student_ids[]" and submit it to its controller?
It is not possible. I solved this problem by using javascript.

Form Refactoring Rails

I am currently creating a form in my rails application but would like some advice on refactoring it. The form is being used to save bagel toppings for an order. The user can select three different toppings (topping1, topping2, and topping3), and the form fields for each one are virtually identical.
ie.
<%= form_for order_item, remote: true do |f| %>
...
<div class="field">
<%= f.label :topping1 do %>
<%= image_tag("http://www.189harwood.com/statics/images/products/ingredients/butter.png", class:"topping") %>
Butter
<% end %>
<%= f.radio_button :topping1, "butter", checked: "checked" %>
</div>
<div class="field">
<%= f.label :topping1 do %>
<%= image_tag("http://www.wpclipart.com/food/dairy/cheese/soft_cream_cheese.png", class:"topping") %>
Cream Cheese
<% end %>
<%= f.radio_button :topping1, "cream cheese" %>
</div>
...
<div class="field">
<%= f.label :topping2 do %>
<%= image_tag("http://www.189harwood.com/statics/images/products/ingredients/butter.png", class:"topping") %>
Butter
<% end %>
<%= f.radio_button :topping2, "butter", checked: "checked" %>
</div>
<div class="field">
<%= f.label :topping2 do %>
<%= image_tag("http://www.wpclipart.com/food/dairy/cheese/soft_cream_cheese.png", class:"topping") %>
Cream Cheese
<% end %>
<%= f.radio_button :topping2, "cream cheese" %>
</div>
...
<%= f.submit "Wrap It Up" %>
<% end %>
Any suggestions on how I can refactor this? Thanks
Try storing the toppings in an array of hashes in your model:
def self.toppings
[{name:'butter', url:'http://www.189harwood.com/statics/images/products/ingredients/butter.png'}, {name:'cream cheese', url:'http://www.wpclipart.com/food/dairy/cheese/soft_cream_cheese.png'}, {...}]
end
In your controller:
my_action
#topping_options = Model.toppings
end
And in your view:
<div class="field">
<% #topping_options.each do |topping| %>
<%= f.label topping[:name].to_sym, topping[:name].humanize %>
<%= image_tag(topping[:url], class:"topping") %>
<%= f.radio_button topping[:name].to_sym %>
<% end %>
</div>

Having a Variable in a Render get transfered to the HTML

Sorry for the confusing title, but I'm not really sure what the exact problem is because I don't know Ruby all that well. Anyway, on to the problem!
So I have a render:
<div class="form" id="dept_div">
<span class="label search_label">Department:</span>
<% query = "<option></option>" %>
<% Department.all.each do |d| %>
<% query << "<option>"+d.dept+"</option>" %>
<% end %>
<%=select_tag :major, query.html_safe, class: "search_tag", id: "dept_drop" %>
</div>
That I try and plug in over here:
<span class="su_label">
<%= f.label :major %>
</span>
<% if !in_mobile_view? %>
<div class = "su_textfield">
<div class="checkbox">
<% else %>
<div data-role="fieldcontain" class="field_group">
<fieldset data-role="controlgroup" data-type="horizontal">
<% end %>
<!-- check privacy preferences to decide whether box should already be checked -->
<% if !hasnoprefs && #user.privacy_prefs.include?("nomajor") %>
<%= check_box_tag "major", 1, true %>
<% else %>
<%= check_box_tag "major" %>
<% end %>
<%= label_tag 'major', 'Hide' %>
<% if !in_mobile_view? %>
</div>
<%= render 'courses/form_partials/majors' %>
</div>
<% else %>
<%= f.text_field :major, class: "settings_inputfield" %>
</fieldset>
What I want is the variable major (which in the class User) to become the item selected from the render (which is a drop down menu). Any ideas?
Try...
<%= f.collection_select :major, query, :id, :major, {:include_blank => 'None' } %>

Rails - Use the same form with new/edit using fields_for

I have 5 models,
Person
person_car
car (has many tires)
person_car_tire
tire (belongs to car)
so I have this view
_form.html.erb
<%= form_for(#person) do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div>
<% Car.all.each do |c|%>
<div class="field">
<%= f.fields_for(:person_cars) do |ff|%>
Car Name: <%= ff.check_box :car_id %>|<%= c.car_name%>
<% c.tires.each do |b|%>
<div class="field">
<%= ff.fields_for(:person_car_tires) do |fff|%>
Tire: <%#= fff.check_box :tire_id%>|<%= b.tire_name%>
<%end%>
</div>
<%end%>
<%end%>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
And when I save it works perfectly, the problem comes when I want to edit using this form because it duplicates data of each car 4 times in the view. I've been searching and fields for allows extra options so I made:
<%= form_for(#person) do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div>
<% #person.cars.each do |c|%>
<div class="field">
<%= f.fields_for(:person_cars, c) do |ff|%>
Actividad: <%= ff.check_box :car_id %> | <%= c.car.name%>
<% c.person_car_tires.each do |t|%>
<div class="field">
<%= ff.fields_for(:person_car_tires, t) do |fff|%>
Tarea: <%#= fff.check_box :tire_id%>|<%#= t.tire.name%>
<%end%>
</div>
<%end%>
<%end%>
</div>
<%end%>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
and it now works, but only show the cars and tires that I've selected on the new action. not all as I wanted (because if I use the first form it duplicates checkboxes in the view).
How can I use the same form for both actions?
Hope someone can help me.
You can use the same _form partial for both new and edit. You just need to pass local variables set to different values to this form. Basically, whatever differs, abstract it away as a parameter (local variable) to this function-like partial.

Resources