Rails - Multiple Select Update all objects of model - ruby-on-rails

I have a 'country' model in my app with attributes name and status. If a country is activated, its status will be 1. Admin type of user can toggle this so I have given a multiple select dropdown for the same. My problem, how to update all the selected/unselected countries at one hit of submit button ?
My form on settings page for Admin user -
<%= simple_form_for #country do |form| %>
<%= form.collection_select :name, Country.order(:name), :id, :name, {:selected => #selected}, {:multiple => true, :class =>"ui fluid selection dropdown"} %>
<%= form.submit 'Submit' %>
<% end %>
Controller -
def settings
#country = Country.new
#selected = Country.where(status: '1').pluck(:id)
end
And the script -
<script>
$(document).on('turbolinks:load', function() {
$('.ui.dropdown').dropdown();
});

Related

Rails - Show objects related to user in form dropdown

In my rails application the following relationships exist:
user belongs_to :team ,
element belongs_to :team ,
task belongs_to :element
A user can then create a task which belongs to an element.
When a user is creating a task, they can select the element they would like the task to belong to. How do I show only the elements that belong to the current_user's team? I am using Devise to get the current_user.
The samples below do not work.
<div class="field">
<%= form.label :element_id %>
<%= form.select :element_id, options_for_select(Element.current_user.team_id.map{|s|[s.title, s.id]}),{ :multiple => true} %>
</div>
I also tried to call the method below from the tasks_controller.rb file but it didnt work either
def new
#task = Task.new
#tasks_element_dropdown = Element.current_user.team_id.map{|s|[s.title, s.id]}
end
In the tasks/_form.html.erb file, I called the method with the code below
<%= form.select :element_id, options_for_select(#tasks_element_dropdown),{ :multiple => true} %>
When I tried the example below it does work but it displays all elements, and I only want the elements that belong to the user's team to display
<div class="field">
<%= form.label :element_id %>
<%= form.select :element_id, options_for_select(Element.all.map{|s|[s.title, s.id]}),{ :multiple => true} %>
</div>
The problem is in the following code, which should return the elements:
Element.current_user.team_id.map{|s|[s.title, s.id]}
Since you have a user, you can get the team: current_user.team
And then get the elements of the team (as long as has_many :elements is defined in the Team class): current_user.team.elements
Thus, the final code should be something like:
<div class="field">
<%= form.label :element_id %>
<%= form.select :element_id, options_for_select(current_user.team.elements.map{ |s| [s.title, s.id] }),{ :multiple => true} %>
</div>

How do I select a car make and then select model according to make?

In my rails project I have two models, Car Make & Car Model, with a 1:M relationship (i.e. one Audi has many Audi models).
In my Views page, I want a form with two input fields for car make & car model. Ideally, I will be able to input a car make (i.e. Audi) and the second input field will have a drop down menu with all the models available for the make (2016 Audi A6, 2017 Audi A7).
I've set up all the relations and in the models I have saved a foreign key of the make.
currently in _form.html.erb I have
<div class="field">
<%= f.label :make_id, "Make:"%><br>
<%#= f.number_field :make_id %>
<%= f.collection_select :make_id, Make.all,
:id,:makes_info, {:include_blank => 'Please Select'} %>
</div>
<div class="field">
<%= f.label :model_id, "Model:" %><br>
<%= f.collection_select :model_id, Model.all,
:id,:model_info, {:include_blank => 'Please Select'} %>
</div>
If you want it to truly be dynamic, you would need to use an AJAX request to update the second select after the first is picked. You'd also need to use the options_for_select method inside of the select tag
Some more info to accompany what was already provided.
It's known as dynamic select boxes:
#config/routes.rb
resources :makes do
get :models, on: :collection #-> url.com/makes/models
end
#app/controllers/makes_controller.rb
class MakesController < ApplicationController
def models
#make = Make.find(params[:make][:make_id])
respond_to do |format|
format.js
end
end
end
#app/views/makes/models.js.erb
$select = $("select#models");
$select.empty();
<% #make.models.each do |model| %>
$select.append($('<option>').text(<%=j model.name %>).attr('value', <%= model.id %>));
<% end %>
#views
<%= f.collection_select :make_id, Make.all, :id, :makes_info, {include_blank: 'Please Select'}, { data: { remote: true, url: make_models_path }} %>
<%= f.collection_select :model_id, Model.all, :id,:model_info, {include_blank: 'Please Select'}, { id: "models" } %>

Adding or updating record with user id

Ruby on Rails 3, I have an edit page with two select_tag submissions. One has users that have the attribute :attend = "Yes" and the other has users that have the attribute :attend = "No" or nil. I am trying to get the select_tag submissions to create or update the Certificate table for the user. As of now I know it is POSTing the user id and name. I do not know how to get the controller or model to take the user id and create or update with the :attend attribute value of "Yes" or "No". The app will create a new record with the correct user id but not with :attend since it is not in my select_tag submission.
Here is my edit:
<%= form_for #untrained do |f| %>
<p> Trained Users </p>
<%= select_tag "certificate[user_id]", options_for_select(#current_trained.collect{|x| [x.name, x.id]}), {:multiple => :multiple} %>
<%= f.submit "Un-Train", class: "btn btn-large btn-primary" %>
<% end %>
<%= form_for #trained do |f| %>
<p> Non-Trained Users </p>
<%= select_tag "certificate[user_id]", options_for_select(#non_trained.collect{|x| [x.name, x.id]}), {:multiple => :multiple} %>
<%= f.submit "Trained", class: "btn btn-large btn-primary" %>
<% end %>
Here is my controller:
#trained = Certificate.new(params[:certificate])
#untrained = Certificate.update(params[:user_id])
Here is my model:
attr_accessible :attend, :pass, :user_id
belongs_to :user
validates :user_id, presence: true
How do you set the controller to create or update a new record with :attend as "Yes"?
How do you update the record with :attend as "No"?
Thank you
Have u tried in the controller after
if #trained.save
put
#trained.update_attributes(attend: "yes")
or no depending on the type u want.
Also have a look at this for the create/update method in rails.
create_or_update method in rails

Rails - Dynamic Select - Collection Select

I've been trying to get some dynamic select functionality working, but despite many different tutorial i've yet to get it to work. For ease of reading, i've brought the code examples down to basics. Any advise would be greatly appreciated.
On the faults page, i need to assign a company and contact to the fault, but I only want to be able to see the contacts associated with the selected company
Fault - belongs_to :company, :user, :contact
User - has_many :faults
Contacts - has_and_belongs_to_many :companies
Company - has_and_belongs_to_many :contacts, has_many :faults
/faults/_form.html.erb
<%= f.label :company, "Company:" %>
<%= collection_select(:fault,:company_id,#companies,:id,:full_name, :prompt => "Please select a company") %></br>
<%= f.label :contact, "Contact:" %>
<%= f.collection_select :contact_id, #contacts, :id, :name, :prompt => "Select a Contact" %>
<%= link_to "Add New Contact", {:controller => "companies", :action => "index"}, :confirm => "To add a contact for a company you need to do this from the companies page." %></br>
Gotcha. Using UJS you can dynamically populate your select in 5 steps.
Add class names to your selects in the view
Add JavaScript (or CoffeeScript) to watch the changes on the select element
Create a controller method to fetch the info you need based on your selection
Add a route to match your new controller method
Create a UJS view to update your contacts select
So,
Add class names:
<%= f.label :company, "Company:" %>
<%= collection_select(:fault,:company_id,#companies,:id,:name, {:prompt => "Please select a company"}, {:class => "company_selection"}) %>
<%= f.label :contact, "Contact:" %>
<%= f.collection_select :contact_id, #contacts, :id, :name, {:prompt => "Select a Contact"}, {:class=>"contact_selection"} %>
Throw in some CoffeeScript (app/assets/javascripts/faults.js.coffee)
$(document).ready ->
$(".company_selection").on "change", ->
$.ajax
url: "/faults/get_contacts"
type: "GET"
dataType: "script"
data:
company_id: $('.company_selection option:selected').val()
Update your faults controller
def get_contacts
#company = Company.find params[:company_id]
#contacts = #company.contacts
end
Add a route to your new method
resources :faults do
collection do
get 'get_contacts', to: "faults#get_contacts"
end
end
Add the UJS file (app/views/faults/get_contacts.js.erb)
$('.contact_selection').empty();
$('.contact_selection').append( $('<option>Select the Contact</option>'));
<% #contacts.each do |contact| %>
$('.contact_selection').append($('<option value="<%= contact.id %>"><%= contact.name %></option>'));
<% end %>
Vanilla JS Option
This can be achieved with vanilla javascript only. Make sure that there is a route at companies/[id]/contacts.json which returns correct data.
const select = document.querySelector('#company_id');
select.addEventListener('change',function(e) {
axios.get(`/companies/${e.target.value}/contacts.json`)
.then((res) => {
let contactSelect = document.querySelector('#contact_id')
contactSelect.innerHTML = ''
res.data.map((model, i) => {
contactSelect.options[i] = new Option(model.name, model.id);
})
})
});

How would I reset my Chosen select menu after creating a resource?

How does one reset a Chosen plugin field after resource is created by Javascript?
I create a dog and can get the regular form fields to reset but not the select menu using the Chosen plugin:
dogs/create.js.erb
$('#dogs').prepend('<%= escape_javascript(render(#dog)) %>');
$('.add-dog-form > form')[0].reset();
This is successful reset, just not with the chosen menu which is called from my application.js:
jQuery( function($) {
// Chosen Select Menu
$('.category-select').chosen().trigger("liszt:updated");
});
Than my form:
<%= form_for(#dog, :remote => true) do |f| %>
<%= f.label :name, "Name" %>
<%= f.text_field :name %>
<%= f.label :category, "Categories" %>
<%= f.select :category_ids, Category.all.collect {|c| [c.name, c.id]}, {}, { :multiple => true, :class => "category-select" } %>
<% end %>
So again, how does one reset a Chosen plugin field after resource is created by Javascript?
Try this:
dogs/create.js.erb
$('#dogs').prepend('<%= escape_javascript(render(#dog)) %>');
$('.add-dog-form > form')[0].reset();
$('.category-select').chosen().trigger("liszt:updated");
You basically have to trigger the reset again inside create.js.erb.

Resources