Rails 5 collection_select: Showing multiple attributes in one column - ruby-on-rails

I'm trying to make a collection select which shows two attributes from two different models.
I want to select an account. The account has a name and an owner. The owner is a model which also has the attribute name.
When using the collection select I want it to show: account.name + owner.name. This is currently the collection_select I have which only shows the account.name
<div class="field">
<%= f.label :to_account_id %>
<%= f.collection_select :to_account_id, Account.all, :id, :name %>
</div>
ex: A account has name Main account and the owner of the account is Stan, when selecting it should show Stan - Main account.
worked with:
<%= f.collection_select :to_account_id, Account.all.map{|a| ["#{a.owner.name} - #{a.name}", a.id] },:second,:first %>

Try following code
<%= f.collection_select :to_account_id, Account.all.map{|a| ["#{a.name} - #{a.owner.name}", a.id] } %>

class Classification < ApplicationRecord
def class_detail
"#{definition} #{description}"
end
end
<%= form.collection_select(:classification_id, Classification.order(:classification), :id, :class_detail, prompt: true)%>

Related

Ruby on Rails - user forms reference param other than ID

I created the user table and I created a scaffold from there. the user table only has 1 attribute name. I created 1 user called "John"
I then created another scaffold called order generation which references the user (i.e the user must exist before i can order)
<div class="field">
<%= form.label :user_id %>
<%= form.text_field :user_id %>
</div>
However what I want is to reference the username john and then map back to the user_id. Is there a way to do this using a drop down list and display the username and in the backend, it will pass the user ID ?
update: I tried to do this but it doesnt seem to work also
<div class="field">
<%= form.label :user_id %>
<%= form.select :user_id, options_for_select(#users.each { |c| [c.name, c.id] })%>
</div>
You need
<%= form.select :user_id, options_for_select(User.all.map{|u|[u.name, u.id]}) %>
Also as pointed out in the comments by #eyeslandic this will also work
options_for_select(User.pluck(:name, :id))
Which I think is actually nicer syntax

Rails: Automatically assign parameters in a form

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.

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" } %>

Rails link models in a form DRY

I am trying to link multiple rails models in my app. I am trying to let users create reviews on a product using a form. I am trying to use the rails DRY principle.
I first made a bat table with bat name, model year, and an image. Then I created a manufacturer table which only lists the names of the manufacturers of bats. My bats model belongs_to :manufacturer and my manufacturer model has_many :bats.
Instead of creating multiple tables using manufacturer, (listing the name of the manufacturer at least 3 times for each bat) how can I link my two models together?
My form is submitted to the review model. In the form I already have <%= f.collection_select :bat_id, Manufacturer.all, :id, :manufacturer, include_blank: true %>, which lists all of the possible manufacturers in a drop down menu. HOWEVER, nothing is submitted to the :bat_id parameter in the review form when submitted.
--One guess is to have the manufacturer_id integer stored in the bat model as an integer under the column manufacturer_id(Note: already done this, but I don't know how to submit that in a form?)
--Another guess is to have the bat model inherit from the manufacturer model
Any help is greatly appreciated
My full form:
<%= form_for(#review) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field" align= "center">
<h3>Select bat</h3>
<%= f.collection_select :bat_id, Manufacturer.all, :id, :manufacturer, 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 %>
according to the documentation
http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select
the params in the collection_select is supposed to be:
f.collection_select(:post, :author_id, Author.all, :id,
:name_with_initial, prompt: true)
where post is the Model,author_id is the attribute
or you could try using:
=f.select( :bat_id, options_from_collection_for_select(#manufacturers,"id","manufacturer",
f.object. bat_id),{})
and put the
#manufacturers = Manufacturer.all
inside the controller

Showing name in drop down select box

I want to create a task and assign to a particular user who has_one profile with first name and last name.
And also user has_many tasks.
My new task form is
<%= form_for :task do |f| %>
<div>
<%= f.label :task %>
<%= f.text_area :task %>
</div>
<div>
<%= f.label :assigned_to %>
<%= f.collection_select(:assigned_to, User.profile.all, :fist_name, :fist_name, :include_blank => 'None')%>
</div>
in the collection select I should display something like " Sam Parker (sam#org.com)" like this all the users should be available in the collection select field.
Can anyone help me how to display it.
First of all read the documentation here:
http://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-collection_select
I guess you need to create a method that returns the option's text, for example:
class User < ActiveRecordBase
# ...
def label_for_select
"#{profile.full_name} (#{profile.email})"
end
end
Then, in your view it would be something like:
<div>
<%= f.label :assigned_to_id %>
<%= f.collection_select(:assigned_to_id, User.all, :id, :label_for_select, :include_blank => 'None')%>
</div>
Notice that the form sets the assigned_to_id not the assign_to ruby object. Rails will instantiate the assign_to object based on this id.

Resources