collection_select issue in rails with passing reference_id in rails - ruby-on-rails

i am passing reference id as from requirement table in collection_select but instead of showing team_id as drop-down i want to user as team_name from team table by using team_id.
also i want distinct record.
form.html.erb
<div class="field columns large-4">
<%= form.label :team, :class=>"" %>
<%= form.collection_select :requirement_id, #project.requirements, :id, :team_id, prompt: true %>
</div>

Try following, Use delegate in model
In models/requirement.rb
delegate :name, to: :team, prefix: true
or use custom method
def team_name
team ? team.name : 'No team associated'
end
& then value_method in view
<%= form.collection_select :requirement_id, #project.requirements, :id, :team_name, prompt: true %>

Related

Model with nested attributes doesn't show fields_for in field that is not an attribute in the model

I have an Exam and an ExamBattery that is just a collection of Exams. They have a has_and_belong_to_many declaration for each other, and ExamBattery accepts nested attributes for Exam, like so:
class Exam < ApplicationRecord
has_and_belongs_to_many :exam_batteries
validates_presence_of :name
end
class ExamBattery < ApplicationRecord
has_and_belongs_to_many :exams
accepts_nested_attributes_for :exams, reject_if: lambda { |attrs| attrs['name'].blank? }
validates_presence_of :name
end
When I create a new Exam, I want to be able to assign it to one or many ExamBatteries, so in ExamsController I whitelisted the array exam_battery_ids to accept multiple ExamBatteries to assign them to the current Exam (no other change was made, the controller is just from the scaffold):
def exam_params
params.require(:exam).permit(:name, :description, :order, :price, exam_battery_ids: [])
end
Also, in the view exams/new I added a multiple select to send the desired exam_battery_ids as params:
<%= form_with(model: exam, local: true) do |form| %>
# ... typical scaffold code
<div class="field">
<% selected = exam.exam_batteries.collect { |eb| eb.id } %>
<%= form.label :exam_battery_ids, 'Add batteries:' %>
<%= form.select :exam_battery_ids,
options_from_collection_for_select(ExamBattery.all, :id, :name, selected),
{ prompt: 'None' },
multiple: true %>
</div>
<% end %>
The idea is to be able to create a new ExamBattery with new Exams in it, in the same form (I haven't wrote that part yet, I can only edit for now). Also, when I edit an ExamBattery I want to be able to edit its Exams and even assign them to other ExamBatteries (if I select 'None', or JUST another exam battery, it would stop being assigned to the current ExamBattery), so in exam_batteries/edit (actually, the form partial in it) I have this code:
<%= form_with(model: exam_battery, local: true) do |form| %>
# ... normal scaffold code
<div class="field">
<!-- it should be exam_battery[exams_attributes][#_of_field][order] -->
<!-- it is exam_battery[exam_battery_ids][] -->
<% selected = exam_battery.exams.map { |exam| exam.id } %>
<%= form.label :exam_battery_ids, 'Edit batteries:' %>
<%= form.select :exam_battery_ids,
options_from_collection_for_select(ExamBattery.all, :id, :name, selected),
{ prompt: 'None' },
multiple: true %>
</div>
<% end %>
And in ExamBatteriesController I whitelisted the exam_batteries_attributes, with exam_battery_ids: [] as a param:
params.require(:exam_battery).permit(:name, :certification, exams_attributes: [:name, :description, :order, :price, exam_battery_ids: []])
But when in the ExamBattery form I try to edit the Exam's exam_batteries, the info doesn't update, because the params are like this:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"blah", "exam_battery"=>{"name"=>"Battery1", "certification"=>"test1", "exams_attributes"=>{"0"=>{"name"=>"Exam1", "description"=>"", "order"=>"", "id"=>"3"}, "1"=>{"name"=>"Exam2", "description"=>"", "order"=>"", "id"=>"4"}, "2"=>{"name"=>"Exam3", "description"=>"", "order"=>"", "id"=>"5"}}, "exam_battery_ids"=>["", "", "", "", "", "3"]}, "commit"=>"Update Exam battery", "id"=>"3"}
The exam_battery_ids are sent as a different param because the select name is exam_battery[exam_battery_ids][] instead of something like exam_battery[exams_attributes][0][name], as it happens with the other fields. How can I fix that?
Thanks.
I had an error in the form. In exam_batteries/edit I didn't notice I was using the form_with variable (form) and not the fields_for variable (builder), so it should be like this:
<div class="field">
<!-- it should be exam_battery[exams_attributes][0][order] -->
<!-- it is exam_battery[exam_battery_ids][] -->
<% selected = exam_battery.exams.map { |exam| exam.id } %>
<%= builder.label :exam_battery_ids, 'Escoge una batería' %>
<%= builder.select :exam_battery_ids,
options_from_collection_for_select(ExamBattery.all, :id, :name, selected),
{
include_hidden: false,
prompt: 'Ninguna'
},
multiple: true %>
</div>
With that it should work.
The only issue now is that I can't get the selected batteries when I show them in the fields_for, but I'm working on it.
UPDATE: I can show the current exam_batteries of the exam in the nested form by replacing the selected variable in the view with this:
<% selected = exam_battery.exams[builder.options[:child_index]].exam_batteries.map { |eb| eb.id } %>
If you know about a cleaner method, please let me know.

Rails - How to call values from one model into another model form

I'm working on some app and I have 2 models. Categories in which I create category names and Question. Category has_many questions and Question belongs_to Category.
I've added category_id to Question model.
Now I need to take all Category_names and display them in form where I create Question so User can choose in which category_name will save question.
I've tried something like this in firs line of code but not working.
<%= f.input :category_id, Category.all.map(&:name) %>
<%= f.input :question_name, wrapper: :vertical_text_input, as: :text %>
<%= link_to "Markdown help", "http://assemble.io/docs/Cheatsheet-Markdown.html", target: "_blank", class: "right" %>
<%= f.input :answer %>
<%= f.input :image, as: :attachinary %>
QUESTION: How to display all Category names in form where I create new Questions?
you may wanna use a select box and use the collection select rails helper :
f.collection_select(:category_id, Category.all, :id, :name)
Also you can use this way.
<%= f.select :category_id, Category.all.map(&:name), {prompt:"Choose Category"}%>
#Jhon suggestion.
<%= f.select :category_id, Category.pluck(:name), {prompt:"Choose Category"}%>

Rails 5 collection_select: Showing multiple attributes in one column

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)%>

Can't pass through variable from collection select in rails

I'm trying to use a collection select and from there go to my user_show page, but I can't seem to figure out how to send the selected variable through to be displayed.
Here is my current code:
<%= form_tag user_path(:id), :method => :post do %>
<%= collection_select(:user, :id, User.all, :id, :name) %>
<button type="submit">Sign In</button>
<% end %>
This is the closest I've gotten, but it is reading the :id as id. What is the correct way to do this?
Your collection_select should be like this (with explanation of each field):
collection_select(
:user, # field namespace
:user_id, # field name
# result of these two params will be: <select name="user[user_id]">
# then you should specify some collection or array of rows.
# In your example it is:
User.all,
# then you should specify methods for generating options
:id, # this is name of method that will be called for every row, result will be set as key
:name, # this is name of method that will be called for every row, result will be set as value
# as a result, every option will be generated by the following rule:
# 'user' is an element in the collection or array
)
So, change your collection_select to this:
<%= collection_select(:user, :user_id, User.all, :id, :name) %>
You probably need:
<%= form_tag user_path(:id), :method => :post do %>
<%= collection_select(:user, :user_id, User.all, :id, :name) %>
<button type="submit">Sign In</button>
<% end %>

Rails form dropdown using two text_method

I am creating a form has a drop down selection. I want to use two "text_method"s for the input but I am unsure how to do this. I want to include the year and name (both are two different columns in my rails model.
Here is what I have but it does not work:
<%= f.collection_select :bat_id, Bat.all, :id, :model_year, :model_name, include_blank: true %>
Here is the official documentation- http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select
Use this in your view:
<%= f.collection_select :bat_id, Bat.all, :id, :model_year_and_name, include_blank: true %>
Add a method like this to your Bat model:
def model_year_and_name
"#{model_year} #{model_name}"
end

Resources