In Ruby on Rails if I have class/model A that reference class/model B. Let us say that (just examples)
class B
@attr_acessor :name
end
class A
@attr_accessor :B
@attr_accessor :amount
end
How do I make a form such that when creating A, I get a list of all potential B's and so the references is made for me on A object creation? It would be brilliant if I could search in the list as well.
The classes are just for an abstract example.
CodePudding user response:
To create a form that allows you to select a value from a list of potential objects of class B and create an object of class A with a reference to the selected object of class B, you can use the select method in your form.
Here is an example of how you can use the select method to create a form that allows you to select a value from a list of potential objects of class B:
<%= form_for @a do |f| %>
<%= f.label :amount %>
<%= f.text_field :amount %>
<%= f.label :b %>
<%= f.select :b, B.all.map { |b| [b.name, b.id] }, {}, { multiple: true } %>
<%= f.submit %>
<% end %>
This form will display a text field for the amount attribute of the A object, and a select box for the b attribute. The select box will contain a list of all the objects of class B, with the name attribute of each object as the display text and the id attribute as the value. When the form is submitted, the selected value will be used to create the reference to the selected object of class B on the A object.
If you want to be able to search the list of potential objects of class B, you can use the collection_select method instead of the select method. The collection_select method allows you to specify a search field that will be used to filter the list of potential objects.
Here is an example of how you can use the collection_select method to create a form with a searchable select box:
<%= form_for @a do |f| %>
<%= f.label :amount %>
<%= f.text_field :amount %>
<%= f.label :b %>
<%= f.collection_select :b, B.all, :id, :name, {}, { multiple: true, include_blank: true } %>
<%= f.submit %>
<% end %>
This form will display a text field for the amount attribute of the A object, and a searchable select box for the b attribute. The select box will contain a list of all the objects of class B, with the name attribute of each object as the display text and the id attribute as the value. When the form is submitted, the selected value will be used to create the reference to the selected object of class B on the A object.
CodePudding user response:
If what you mean are actual database backed models then you do it by using assocations and the collection helpers:
class Foo < ApplicationRecord
has_many :bars
end
class Bar < ApplicationRecord
belongs_to :foo
end
This creates a Foo#bar_ids
getter and a Foo#bar_ids=
setter.
<%= form_with(model: @foo) do |form| %>
<%= form.label(:bar_ids, "Bars") %>
<%= form.collection_checkboxes(:bar_ids, @bars, :id, :label_method) %>
<% end %>
class FoosController < ApplicationController
def new
@foo = Foo.new
@bars = Bar.all
end
def create
@foo = Foo.new(foo_params)
if @foo.save
redirect_to @foo
else
@bars = Bar.all
render :new
end
end
private
def foo_params
params.require(:foo)
.permit(:a, :b, bar_ids: [])
end
end
It would be brilliant if I could search in the list as well.
You should learn how to walk before you do your first marathon.