Populate Dropdown based on another dropdown in ruby on rails - ruby-on-rails

I have a two different fields in my form like below.
<div class="field">
<%= f.label :Master_Survey %><br/>
<%= f.select :master_survey, Condition::MasterSurvey.all.map{|e| [e.Master_Survey_Code]}, { :prompt => 'Please Select' } %>
</div>
<div class="field">
<%= f.label :Element_Code %><br/>
<%= f.select :Element_Code, Condition::Element.all.map{|e| [e.Element, e.Element_Code]}, { :prompt => 'Please Select' } %>
</div>
I want the second field should disabled unless the first got selected. And The Second field Element code should change the value depend upon the First field Master Survey selected. I have a Master Survey Code in the Elements Table.

If these two models are related via has_many/belongs_to or something similar, the best bet is going to use the grouped_collection_select method for your drop downs. This will organize your drop down into a tabbed-list (using optgroup), but then doing some jQuery magic to make the 2 drop down selections dynamic and chained!
Ryan Bates has a RailsCast that explains in great detail exactly how to do this. If you don't have a pro-subscription to RailsCasts, I highly recommend getting one so you can easily find out how to do things like this :)
Hope this points you in the right direction!

Related

Making a dropdown and getting the value in Rails

I have a many-to-many relation between my User model and my Project model for the purpose of assigning projects to users. I'm now trying to impement the feature for actual assignment using a dropdown containing the projects on the edit user page. My code looks like this, but I can't seem to figure out how send the selected value back to the controller once the button is clicked:
<div class="input-group my-2">
<%= collection_select('user', 'project', Project.all, :id, :name, include_blank: true) %>
<div class="input-group-append">
<%= link_to '<div class="btn btn-outline-primary">Toggle access to selected project</div>'.html_safe, toggle_project_access_user_url %>
</div>
</div>
I've tried using the suggestions for JS I've found, but I think I'm missing some knowlegde on how to implement the functionality completely with those.
Working with Javascript in Rails covers this.
Use form_with to set up a form with data-remote=true. Then proceed as normal.
form_with url: toggle_project_access_user_url, method: :patch do |f|
f.collection_select(:project_id, Project.all, :id, :name, include_blank: true)
f.submit("Toggle access to selected project")
end
This will send a POST to toggle_project_access_user_url with a hidden _method input indicating it's a PATCH. Use a hook on ajax:success to update the page.

How to determine button id in another view depending on a different view Rails

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)

Is it okay to read date from database in the view template in Ruby on Rails?

I am revisiting the basics of MVC and Ruby on Rails. I am looking at my code and found that I have used this select tag in my Edit User Profile view.
<div class="row">
<div class="panel panel-primary">
<div class="panel-heading">
<%= f.label :country_id, "From*" %>
</div>
<div class="panel-body">
<%= f.select :country_id, Country.order(:name).collect {|p| [ p.name, p.id ] }, {}, { :class => 'form-control' } %>
</div>
</div>
</div>
I am accessing the Country table in the view. I am pretty sure this should not be done but somehow it works. Why does it work? What is the correct way to do it?
Thanks.
There's no reason why what you have won't work. Remember, a view template is an "embedded ruby" file. It has Ruby embedded in an HTML template. When the view is "rendered" by the controller, all of the code inside it gets executed and whatever output is generated by its Ruby code becomes part of the HTMl document. In this case, the output generated by the Ruby code is a bunch of HTML tags and Country names and IDs.
To avoid having this logic in the view, you would put it in the controller and save it to an instance variable (i.e. something like #select_vals) and then reference that variable in the view template.
It works because Rails provides a lot of 'magic' under the hood; this functionality, at a guess, is probably part of the ActionView library (I haven't checked).
One of the fundamental principles of the MVC model is that you don't do this in the view. This logic should be done in the controller.
The correct way ->
in Controller method:
#country_vals = Country.order(:name).pluck(:name, :id)
No need to use collect().
In your view:
<%= f.select :country_id, #country_vals, {}, { :class => 'form-control' } %>

Rails Year Make Model Dynamic Menus

Calling all Rails superheroes! I'm racking my brains with this one and can't find a solution anywhere online...I want to build year/make/model drop-downs to select a car from a table of 30,000+ different cars. The table is called car_variants. Here's a link to a similar thing on kbb.org
The Year is selected first which then populates the Make drop-down with those that were available in that year. This in turn populates the Model drop-down. All this filtering overcomes the dreadful problem of having the 30,000 car_variants in one unusable drop-down.
Unfortunately I don't have enough reputation to post my entity diagram, but essentially...
a car_make has many car_models
a car_model has many car_variants
a car_year has many car_variants
SIDE NOTE Since the car_variants table will be populated by importing an excel spreadsheet, I decided to join car_year to car_variants directly rather than saying a car_year has many car_models. That may or may not affect the challenge below.
The car_variants model ( a table of virtually every car since 1984) stores the car_year_id and the car_model_id. (car_make is obvious through car_model)
Now... along comes the user. They want to select their car from the car_variants table then add their car's nickname and license_plate. The user potentially has many cars so the car_variant_id's can't be stored in the user table. Instead we have a car table which contains the users cars.
a car_variant has many cars (think of a car as being like an instance of a car_variant)
a user has many cars
Ryan Bates did an excellent screencast about Dynamic Select Menus. In his example (Countries and States), he used grouped_collection_select and some javascript. That certainly appears to be heading in the right direction for this challenge too, but this is more complex because there are more has_many relationships than grouped_collection_select seems to be able to handle.
I have successfully coded the car form with 3 drop-downs for year, make and model...
<%= simple_form_for(#car) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<!-- select year to filter make dropdown -->
<p>Year</p>
<%= select_tag :car_year, options_for_select(CarYear.all.collect {|e| ["#{e.year}", e.id] }), :include_blank => true %>
<!-- Select make to filter model dropdown -->
<p>Make</p>
<%= select_tag :car_make, options_for_select(CarMake.all.collect {|e| ["#{e.name}", e.id] }), :include_blank => true %>
<!-- Select model -->
<p>Model (grouped collection select)</p>
<%= f.grouped_collection_select :car_variant_id, CarMake.order(:name), :car_models, :name, :id, :name, include_blank: true %>
<%= f.input :nickname, :hint => "If you've given your car a nickname enter it here, otherwise just leave it blank." %>
<%= f.input :plate %>
<%= f.hidden_field :user_id, :value => current_user.id %>
</div>
<div class="form-actions">
<%= f.button :submit, "Add Car" %>
</div>
<% end %>
...now how do I tie them all together so they filter one another then return the car_variant_id to be stored in the car_form.
After several late bleary nights, I'm out of ideas.

Posting to database from dropdown menu Rails

I have created a dropdown menu that is pulling Cities and Countries from two database tables (named citie and country).
I am using the following collection_select tag:
<section class="field">
<%= f.label :city %>
<%= f.collection_select(:id, Citie.all, :id, :city) %>
</section>
But when I submit my form nothing is being posted into my jobs table (the form is to generate a new job).
I have searched to find a solution for this and am sure I am just missing a small part but can't seem to figure out what it is and why it's not working.
Any advice and a solution would be much appreciated! Thanks
I'm not terribly familliar with collection_select but shouldn't you give the association name as the first argument? e.g.
<%= f.collection_select(:city, Citie.all, :id, :city) %>

Resources