This is the template with multiple => true, but when i remove the multiple the selection tray works perfectly and takes in a single value.
What i need is multiple options to be selected and to be stored in the confirer_string as a string.
The problem i'm encountering is that all the options are listed but they coudn't be selected though they can be clicked on.
new.html.erb
<%= form_with(model: #base, local: true) do |form| %>
<%= form.label :description %>
<%= form.text_field :description, id: :base_tbl_description %>
<%= form.label :confirer_string %>
<%= form.collection_select(:confirer_string, Confirmer.all , :position, :name,{ :prompt => "Please select" }, { :multiple => true } ) %>
<%= form.submit %>
<% end %>
Is it a problem since i'm not using id's but integer fields. And one more thing :confirer_string is of type string.
There are two models, without any association between them. All i'm trying to do is get the list of options from the other model to be listed as option in the selection of primary model. Then the set of selected options will return their position, which will be stored in the confirer_string.
Thing is i cant select anything, not even one option when multiple is true.
UPDATE: i got the multiple select working again but i need to use ctrl+click to select mutliple entries. But the data is not storing, it is giving unpermitted error: conf_string
Just add the {attribute_name: []} in the strong params.
Related
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)
I'm creating a Rails app which allows users to create different animals and assign them attributes.
One of the attributes they an assign is "range". There are currently four types of ranges and each range has a different id:
land - id:1
sea - id:2
air - id:3
underground - id:4
Range has its own controller, model, and view in my app.
Each animal can be created with an id, a name, and a range. But I also have a column entitled range_id, which is what I am using to tie the animal back to the range.
{name:"cat", range:"land"}
#ids are assigned automatically
For views/animals/new.html.erb, I include a form that asks for each animal's attributes.
<h1> Add Animal </h1>
<%= form_for :animal, url: animals_path do |f| %>
<p>
<%= f.label :name %> <br>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :range %> <br>
<%= f.select :range, ['land', 'sea', 'air', 'underground'], :prompt => 'Select One' %>
</p>
<p>
<%= f.submit %>
<p>
<% end %>
My problem is, I need to automatically assign a range_id to each new Animal based on the range. So, if a user created "whale" with a range "sea", that Animal also needs to have a range_id of 2.
How can I do this automatic assignment? Here is my current animal_params method in animals_controller.rb:
private def animal_params
params.require(:animal).permit(:id, :name, :range, :range_id)
end
Should range_id be included there, or what would be the easiest way to alter it automatically?
You can find an answer in the documentation here - you shouldn't be hardcoding these values into your view, and should instead be using ActiveRecord to populate the values for you.
<%= f.select :range_id, options_for_select(Range.all.collect { |range| [range.name, range.id]}, f.object.range_id), {}, class: 'form-control', include_blank: 'Please Select' %>
You can get the reference from here.
I assume that you have a model named Range which has two attributes - name, id. The select box above will show all the ranges in the dropdown.
I've followed this SO answer to add data attributes to my select options.
But I also need a data attribute in my input select wrapper.
Currently, it looks like this:
<% options = #active_users.map do |user| %>
<% [user.full_name, user.id, data: { 'org': user.organization.name }] %>
<% end %>
<%= f.input :user, label: false, required: false, as: :select,
wrapper_html: { class: 'search person js-linked',
data: { 'linked-by': 'person' }
} do
%>
<%= f.select :user_id, options, { include_blank: 'Add user…' },
{ class: 'select optional', placeholder: 'Add user…' }
%>
<% end %>
If I test the option data attribute without the input wrapper data attribute it works like it's supposed to (the data attribute gets added to the options), but as soon as I add the wrapper_html data attribute, like shown in the code above, the data attributes in the select options disappear.
I also tried using a custom input as suggested in this SO answer, but that yielded the same result.
I'd appreciate any insights into why this is happening and how to solve it.
As it turns out, this was caused by the JS code that is handling the linked-by. It was not considering possible data attributes in the options, they just got overwritten.
I am trying to allow a user to input two different things in two different drop down menus from the same form and it will store an integer into a review table.
I want the user to be able to select model_name in one drop down and manufacturer in another drop down. The result will store a bat_id integer into the form. (Telling you which bat the user is selecting)
I have seen a couple questions about date & time but they store the values directly in the model. I am trying to store an integer - bat_id so that the bat_id will directly link the review model to the bat model.
Examples I have found that are close:
How do ruby on rails multi parameter attributes really work (datetime_select)
Rails multiple fields to one model attribute
Using multiple input fields for one attribute
Rails Update Single Attribute with Multiple Fields
My form now:
<%= form_for(#review) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field" align= "center">
<h3>Select Brand</h3>
<%= f.collection_select :manufacturer_id, Manufacturer.all, :id, :manufacturer, include_blank: true %>
<h3>Select Bat</h3>
<%= f.grouped_collection_select :bat_id, Manufacturer.all, :bats, :manufacturer, :id, :model_year_and_name, include_blank: true %>
<h3>What do you like about this bat?</h3>
<%= f.text_area :pros, placeholder: "Enter what you like..." %>
<h3>What do you not like about this bat?</h3>
<%= f.text_area :cons, placeholder: "Enter what you don't like..." %></br>
</div>
<div align="center">
<%= f.submit "Add Review", class: "btn btn-large btn-info" %>
</div>
<% end %>
I am submitting to the review table and trying to submit both of these to the bat_id attribute.
<h3>Select Brand</h3>
<%= f.collection_select :manufacturer_id, Manufacturer.all, :id, :manufacturer, include_blank: true %>
<h3>Select Bat</h3>
<%= f.grouped_collection_select :bat_id, Manufacturer.all, :bats, :manufacturer, :id, :model_year_and_name, include_blank: true %>
In my bat model I have: has_many :reviews & In my reviews model I have: belongs_to :bat
UPDATE: Is it possible to use a hidden field with the combination of javascript and my two inputs to determine my one output bat_id?
Update I changed my dropdown code to what works so that I enter in manufacturer_id & bat_id when both are selected. However I still think there is a way to store one value in my review model. I am using javascript very similiar to this
From a UI perspective this seems broken... users will be able to associate any model year & name with any manufacturer, even if that manufacturer did not produce that model year & name.
Assuming you will introduce some javascript to handle that, from a rails perspective you will get undefined behavior with two :bat_id fields in the same form. I think you need this:
<h3>Select Brand</h3>
<%= f.collection_select :manufacturer_id, Manufacturer.all, :id, :manufacturer, include_blank: true %>
<h3>Select Bat</h3>
<%= f.collection_select :bat_id, Bat.all, :id, :model_year_and_name, include_blank: true %>
Alternatively you can just create one dropdown containing a composite field, like this:
<h3>Select Bat</h3>
<%= f.collection_select :bat_id, Bat.all.sort {|a, b| a.manufacturer_model_year_and_name <=> b.manufacturer_model_year_and_name}, :id, :manufacturer_model_year_and_name, include_blank: true %>
and then in your Bat model introduce something like this:
def manufacturer_model_year_and_name
"#{self.manufacturer.name}: #{self.model_year_and_name}"
end
As discussed in your other answer, you shouldn't need to store the manufacturer_id on your review model.
I would recommend creating a Manufacturer select that isn't accessed in your Review model, but is simply used to filter the list of bats on the form.
The best way to do this is probably to add some custom data attributes to the Bat select.
<%= collection_select :manufacturer, :manufacturer_id, Manufacturer.all, :id, :manufacturer %>
<%= f.select :bat_id, Bat.all.map{ |b| [b.model_year_and_name, b.id, {'data-manufacturer' => b.manufacturer_id}] } %>
Then use some javascript to filter the Bat select when the Manufacturer select is changed.
Unfortunately you cannot just set display: none to an option element to hide it. This does not hide the option in many browsers. So the best method is to use a bit of jQuery to clone the original select every time the manufacturer select is changed, and remove any option that isn't associated with the selected manufacturer. Like so:
// rename the original select and hide it
$('#bat_id').attr('id', 'bat_id_original').hide();
$('#manufacturer_id').on('change', function() {
$('#bat_id').remove(); // remove any bat_id selects
$bat = $('#bat_id_original')
.clone() // clone the original
.attr('id', 'bat_id') // change the ID to the proper id
.insertAfter('#bat_id_original') // place it
.show() // show it
.find(':not(option[data-manufacturer="' + $(this).val() + '"])')
.remove(); // find all options by other manufacturers and remove them
});
You might need to change a few things to get this to work in your installation, but you can view a static demo on jsFiddle here: http://jsfiddle.net/JL6M5/
You will probably need to reject the manufacturer_id field on form submit, avitevet already pointed out this answer which should help there: Rails: Ignoring non-existant attributes passed to create()
I am trying to have a multiple select box. select box will contain all the stores in the DB but the ones that the user belongs to will be selected.
I'm half way there. I got a select box which has all the stores in the database. I'm unable to select the ones that the user belongs to.
I have the following:
<%= select_tag 'stores[]', options_for_select(#stores.map {|s| [s.store_name, s.store_id]},
:selected => #user.stores.map {|j| [j.store_name, j.store_id]}), :multiple => true, :size =>
10 %>
I have a map with stores that a user belongs to. it is in:
#user.stores
after a fair amount of trial and error the following worked for me:
<%= select_tag 'stores[]', options_for_select(#stores.map { |s| [s.store_name, s.store_id] }, #user.stores.pluck(:id)), multiple: true, size: 10 %>
Another way of doing this would be to use the options_from_collection_for_select helper method. It will look something like this:
<%= select_tag 'stores[]', options_from_collection_for_select(#stores, :store_id, :store_name, [4,5,6]), multiple: true, size: '10%' %>