Home > Blockchain >  How to make a form for class A that depends on class B
How to make a form for class A that depends on class B

Time:12-05

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.

  • Related