When implementing the information registration format, it is inevitable to save the selected items (collection, etc.) in the DB. For apps such as flea market, you need to register the prefecture, product status, delivery time, etc. If you assume a questionnaire, you can see it in various situations such as gender and date of birth. I think that many people assume that the item contents are prepared in advance in seed.rb etc. to create a table, but it is no exaggeration to say that this is a useless table.
Active_hash is useful in such a case.
I want to have one table considering the DB load. As a design
Of these, the items (collection_select) that you want to use are the contents 1 to 3. Let's assume this and implement the questionnaire. Please note that this explanation is limited to the implementation of active_hash, and the other steps are omitted.
gem 'active_hash'
Terminal
% bundle install
Generate a model with the g command * Model name is your choice
% rails g model model question
・ Preparation of migration file
When using active_hash Item contents are managed by integer column. This integer column works as an id. Therefore, be sure to add "_id" to the column name. The manual input field is implemented with the usual text column.
00000000000000_create_questions.rb
class CreateQuestions < ActiveRecord::Migration[6.0]
def change
create_table :questions do |t|
t.integer :age_id, null: false
t.integer :sexuality_id, null: false
t.integer :find_item_id, null: false
t.text :comment, null: false
t.timestamps
end
end
end
Then create the table as usual and run the migration file.
% rails db:create
% rails db:migrate
-Create a model file for each item Prepare a model that implements active_hash for 3 items. The migration file is not needed, so add an option to skip it.
% rails g model age --skip-migration
% rails g model sexuality --skip-migration
% rails g model find_item --skip-migration
Let's write the contents of the model prepared for each item
The inside of the generated model probably looks like this at the beginning
class Age < ApplicationRecord
end
To make this a model dedicated to active_hash, edit it as follows.
class Age < ActiveHash::Base
end
This makes it possible to create a pseudo item table within this model. When putting items in this, we will implement it using class methods and hashes. The point to improve readability is to use the first key as id and "give the other key the name you want to treat as an item. Example
class class name< ActiveHash::Base
self.data = [
{ id: 0, hoge: fuga }]
end
Along with this, it becomes as follows.
class Age < ActiveHash::Base
self.data = [
{ id: 0, name: '---' },
{ id: 1, name: '10's' },
{ id: 2, name: '20's' },
{ id: 3, name: '30s' },
{ id: 4, name: 'Forties' },
{ id: 5, name: '50s' },
{ id: 6, name: '60s' },
{ id: 7, name: '70s' },
{ id: 8, name: '80s' },
{ id: 9, name: '90s' }
]
class FindItem < ActiveHash::Base
self.data = [
{ id: 0, example: '---' },
{ id: 1, example: 'I learned from the advertisement' },
{ id: 2, example: 'I learned from an acquaintance's introduction' },
{ id: 3, example: 'I learned from my family introduction' },
{ id: 4, example: 'I knew on the internet' }
]
end
class Sexuality < ActiveHash::Base
self.data = [
{ id: 0, name: '---' },
{ id: 1, name: 'male' },
{ id: 2, name: 'Female' }
]
end
This completes the creation of the pseudo table using active_hash. After that, I will give a description to link with the question model that was created first, which is the basis.
class Question < ApplicationRecord
extend ActiveHash::Associations::ActiveRecordExtensions
belongs_to_active_hash :age
belongs_to_active_hash :sexuality
belongs_to_active_hash :find_item
end
<h1>Please cooperate with the questionnaire about our products</h1>
<div class="wrapper">
<div class="form">
<%= form_with model: @question, local: true do |f| %>
<div class="form-box">
<h3>Please select the age</h3>
<%= f.collection_select(:age_id, Age.all, :id, :name) %>
</div>
<div class="form-box">
<h3>Please select your gender</h3>
<%= f.collection_select(:sexuality_id, Sexuality.all, :id, :name)%>
</div>
<div class="form-box">
<h3>Where did you find out about our products?</h3>
<%= f.collection_select(:find_item_id, FindItem.all, :id, :example)%>
</div>
<div class="form-text">
<h3>Please write down your impressions of using our products as it is easy to use.</h3>
<%= f.text_area :comment %>
</div>
<%= f.submit "Send" %>
<% end %>
</div>
</div>
The point is the argument of collection_select. The first argument is the value passed to params (column name), and the second argument is the item (model name) you want to display.
class QuestionsController < ApplicationController
def index
@question = Question.new
end
def create
# binding.pry
@question = Question.new(question_params)
@question.save
redirect_to root_path
end
private
def question_params
params.require(:question).permit(
:age_id,
:sexuality_id,
:find_item_id,
:comment)
end
end
There is no particular mention here.
I tried to implement it briefly
Please try active_hash by all means.
Recommended Posts