Sorry for this rather simple question, but I know almost nothing of rails.
What I want to do is that when I'm registering an "Articulo" I would like to choose some default values that they would be given by an attribute of a model, specifically, the attribute "rut_prov" from the model "Proovedor".
This is what I have.
articulos_controller.rb
def new
#articulo = Articulo.new
#proveedors = Proveedor.all
respond_with(#articulo)
end
articulos/new.html.erb
<div class="container">
<h1>Nuevo artículo de venta</h1>
<%= render 'form' %>
articulos/_form.html.erb
<div class="field">
<%= f.label :rut_del_proveedor %><br>
<%= f.select :rut_prov, #proveedors, :class => 'genForm_dropBox' %>
</div>
view
So, I know the problem is <%= f.select :rut_prov, #proveedors, :class => 'genForm_dropBox' %>, but I don't know how to make appear as options the values of "rut_prov" of the records I have registered of the model "Proovedor".
You can use collection_select method. The following example displays the result of rut_prov method call on view and passes rut_prov of selected as param:
<%= f.collection_select :rut_prov, #proveedors, :rut_prov, :rut_prov, class: 'getForm_dropBox' %>
BTW, I strongly recommend using English variables/classes/methods names. So it should be Provider instead of Provedoor, Article instead of Articulo etc.
Related
I want to display a list of InvestorTypes (as a radio button) but before each type I should be able to add an explanation of that type. Here is what I've got:
<%= simple_form_for(resource, as: resource_name, url: users_user_experience_level_path(resource_name), html: { method: :put }) do |f| %>
<div class="form-inputs">
<% User::USER_EXPERIENCE_LEVEL.each do |level| %>
<b>Investor type <%= level %></b>
<%= t("user.description.#{level}") %>
<%= f.input :experience_level, collection: [level], as: :radio_buttons, label: false %>
<% end %>
</div>
<div class="form-actions">
<%= f.button :submit, 'Submit' %>
</div>
<% end %>
Which gives me expected view:
Investor type Beginner
Some explanation of what is going on
[checkobox] type Beginner
Investor type Expert
Some clarification of who is an expert and what ever you want to display here
[checkbox] type Expert
Investor type Institutional
Some clarification of who is an institutional client and some legal stuff
[checkbox] type Institutional
But when Submit button is pressed it doesn't pass input value (radio box selection which user chose) into the params:
=> #<ActionController::Parameters {"experience_level"=>""} permitted: true>
[EDIT]
class User < ApplicationRecord
USER_EXPERIENCE_LEVEL = %w[institutional beginner expert].freeze
end
It looks to me like you're using simple form wrong. The "collection" input in Simple Form is expecting to get an entire list of options, not just one option.
Looping in the way you're doing it is creating one group for each experience level, and each group only has one button in it. So it might visually look correct, but it's not functioning the way you intended. Instead you want to create one group of radio buttons for experience level such that each button changes the value of experience level.
Because you're doing this with significant customization around the appearance, it's probably not a good use of Simple Form, and instead you should fall back to the normal Rails form helpers.
You want to pass a block to f.input to get the simple form wrapper and then use the lower level rails helpers:
<%= simple_form_for(resource, as: resource_name, url: users_user_experience_level_path(resource_name), html: { method: :put }) do |f| %>
<div class="form-inputs">
# adds the simple form wrapper
<%= f.input :experience_level do %>
# iterates across the options and yields a input builder to each iteration
<%= f.collection_checkboxes(:experience_level, User::USER_EXPERIENCE_LEVEL, :value_method, :label_method) do |cb| %>
# There are three special methods available:
# object, text and value,
# which are the current item being rendered, its text and value methods, respectively.
<%= t("user.description.#{cb.text}") %>
<%= cb.check_box %>
<% end %>
<% end %>
</div>
<div class="form-actions">
<%= f.button :submit, 'Submit' %>
</div>
<% end %>
If you don't actually have a model you can use #itself to iterate across a flat array:
<%= f.collection_checkboxes(:experience_level, User::USER_EXPERIENCE_LEVEL, :itself, :itself) do |cb| %>
Or an array of pairs:
<%= f.collection_checkboxes(:experience_level, User::USER_EXPERIENCE_LEVEL.zip(User::USER_EXPERIENCE_LEVEL), :first, :last) do |cb| %>
Or even a struct.
I'm making an app where some activities are listed in a table called Fakultety (polish language, sorry), and participants on in another table called Uczestnicy.
I have a submit form where you can submit yourself to an activity, but I'm stuck on passing values to a DB. Firstly, I don't know how to tell to the database on which activity you want to be assigned to (I tried to change the submit button id to an activity id and then passing it into a database but don't know how to do this id: "#{#fakultet.id}" not working) and later I want to count how many people are assigned to field participants in a database Fakultety, but I don't want to pass all the data, just ID of the users from table called Uczestnicy. How to do it? I mean just to pass the ids to another table, and how to tell the database on which activity I want to be assigned to?
This is my form view:
<h1>Zapisujesz sie na fakultet</h1>
<div class="form-group">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#participant, url: zapisy_path) do |f| %>
<p>Imię:</p>
<%= f.text_field :firstName, class: 'form-control' %>
<p>Nazwisko:</p>
<%= f.text_field :lastName, class: 'form-control' %>
<p>Grupa:</p>
<%= f.text_field :group, class: 'form-control' %>
<%= f.submit "Zapisz się", class: "btn btn-primary" id: "#{#fakultet.id}"%>
<% end %>
</div>
</div>
</div>
Does anybody understand me and can help me?
Rails provides form collection helpers that make it really easy to assign associations:
# I'm going to just do this in english
<%= form_for(#activity) do |f| %>
<%= f.collection_select(:participant_ids, Partipicant.all, :id, :name, prompt: true, multiple: :new) %>
# ...
<% end %>
Then whitelist the attribute as an array:
params.require(:activity).permit(:foo, :bar, participants_ids: [])
Thats all you actually need to assign childen to to a parent resource. This is done as a part of the normal create/update actions of the parent resource.
You don't actually need the form for the child records unless you actually want to be creating the record. In that case you can setup a nested resource or if you want to create/edit multiple nested records at the same time as the parent record you can use nested attributes.
First you should rename your models and tables, to English, it's a really bad pattern to use your language, in English it is easier to understand by other devs.
According to the problem, probably what you are looking for is hidden_field
<%= f.hidden_field :fakultet_id, :value => #fakultet.id %>
and if you want to query Fakultety that have user assigned, you can select Fakultety where participant_id is not nil
Fakultety.where.not(participant_id: nil)
On the edit page for this form all of the fields outside of the fields_for tag (inbox name, automatic reconciliation, and a few others not listed here) are all populating based on their corresponding db value. However, everything inside the fields_for tag are not, even though they're posting to the db just fine.
I posted :group_member_roles as an example but there are a few other fields inside their own other fields_for that are doing the same thing. It's just confusing that it will post to the db but not display on edit.
The more I read into fields_for the more I feel like I'm not using it correctly. It seems to be more inclined to populating db tables outside of the one your form is currently referencing, but I'm just trying to serialize data within the inbox table. When I look at the :group_member_roles column I want it to be an array/hash containing process true/false, action add/delete, and a string of values.
#_form.html.erb
<%= form_for(#inbox) do |f| %>
<%= f.label :inbox_name %>
<%= f.text_field :name, placeholder: "Inbox Name" %>
<%= f.label :automatic_reconciliation, "Turn on/off automatic reconciliation" %>
<div class="switch small">
<%= f.check_box :automatic_reconciliation, class: "switch-input" %>
<label class="switch-paddle" for="inbox_automatic_reconciliation">
<span class="show-for-sr">Automatic reconciliation</span>
<span class="switch-active" aria-hidden="true">On</span>
<span class="switch-inactive" aria-hidden="true">Off</span>
</label>
</div>
<%= f.fields_for :group_member_roles do |group_member_roles| %>
<h4>Group Member Roles</h4>
<%= group_member_roles.label :process, "Turn On/Off Processing" %>
<div class="switch small">
<%= group_member_roles.check_box :process, class: "switch-input" %>
<label class="switch-paddle" for="inbox_group_member_roles_process">
<span class="show-for-sr">Group Member Roles Processing</span>
<span class="switch-active" aria-hidden="true">On</span>
<span class="switch-inactive" aria-hidden="true">Off</span>
</label>
</div>
<%= group_member_roles.label :action, class: "hide" %>
<%= group_member_roles.select :action, ["Add", "Delete"], { selected: "Add" }, { class: "hide" } %>
<%= group_member_roles.label :values %>
<%= group_member_roles.text_field :values, placeholder: "1234, 1337, 1986" %>
<% end %>
Thanks in advance for any help or guidance.
The fields were being stored as a hash and the field was looking for an object to populate with so I added an OpenStruct dummy object to the fields_for to make it so. If anyone can think of a better way please let me know as this is pretty ugly code.
<%= f.fields_for :group_member_roles, OpenStruct.new(f.object.group_member_roles) do |group_member_roles| %>
I have a data model that contains the fields for startMonth and endMonth. I also am able to SET them correctly using the following f.select tags, however, when I go to edit the data, the rendered dropdowns do not reflect the proper values stored in the db. Am i setting the f.select tags incorrectly?
<div class="control-group">
<%= f.label "Start Month", :class => 'control-label' %>
<div class="controls">
<%= f.select :startMonth, options_for_select([['January' ,'1'],['February' ,'2'], ['March', '3'],['April' ,'4'], ['May', '5'],['June' ,'6'],['July' ,'7'], ['August', '8'],['September' ,'9'], ['October', '10'],['November' ,'11'], ['December', '12']]), class: "list-select" %>
</div>
<%= f.label "End Month", :class => 'control-label' %>
<div class="controls">
<%= f.select :endMonth, options_for_select([['January' ,'1'],['February' ,'2'], ['March', '3'],['April' ,'4'], ['May', '5'],['June' ,'6'],['July' ,'7'], ['August', '8'],['September' ,'9'], ['October', '10'],['November' ,'11'], ['December', '12']]), class: "list-select" %>
</div>
</div>
Once the data is stored using these dropdowns, it stores it correctly in the database and it shows the correct values on my show page. However, I want the dropdowns to default to the stored values when I return to the edit page. Is there a setting I am forgetting to include?
Alex
You can pass a second argument to the options_for_select method to pre-select the value. For example, assuming your model object is represented by an instance variable called #object, you can pass in #object.endMonth as the second parameter to your options_for_select.:
<%= f.select :endMonth, options_for_select([['January' ,'1'],['February' ,'2'], ['March', '3'],['April' ,'4'], ['May', '5'],['June' ,'6'],['July' ,'7'], ['August', '8'],['September' ,'9'], ['October', '10'],['November' ,'11'], ['December', '12']], #object.endMonth), class: "list-select" %>
Note: the #object.endMonth value must resolve to the same data type as the option value - in this case the number representing the month. See the Rails Guide for details.
I have some custom form (user reputation) that doesn't link with any model directly.
I have several reputation criteria which affects final returation value
Here is code of the form
<%= form_tag("/add_reputing",:method => "POST") do%>
<div class="reputing_column">
<p>
<b>Your feedback:</b>
</p>
<p>
<%= text_area_tag :comment,"",{:class=>"or-form-textarea"} %>
</p>
<%= submit_tag("Submit",:class=>"or-button")%>
</div>
<div class="reputing_column">
<p>
<b>Recomendation:</b>
</p>
<% #criterias.each do |c| %>
<div class="reputing_row">
<label><%= c.name%>:</label>
<div>
<% (c.rating_from .. c.rating_to).each do |i| %>
<%= radio_button_tag "reputing_#{c.id}", i%><%= (i<1)? i : "+#{i}"%>
<% end %>
</div>
</div>
<% end %>
</div>
<% end %>
In controller I need to summirize a values of "reputing_#{c.id}" fields. And then add a record to user reputation table.
How it will be better and properly to process data from this form in controller? I tried to google that problem, but found nothing.
No answers, so I'll try to clarify the dealing with, as you called them, custom forms.
Here's the form for selecting a preferred color via radio buttons.
= form_for :preferences, url: '', method: :post do |f|
- %w[black blue white green red yellow].each do |color|
= f.radio_button :color, color
= f.label :color, color.capitalize, value: color
= f.submit
The cool thing about forms in Rails that they can be used with or without a model. If you have an instance variable called #preferences then this form will respect that and will call the color method on it to determine the "current" color. This color will be selected on the generated form. If this variable doesn't exist it won't be a big deal.
In any case, after submitting the form you'll be able to access the selected color via:
params[:preferences][:color]