SlideShare a Scribd company logo
1 of 23
Download to read offline
Multiple radio buttons
Aka join table nightmares
Multiple radio buttons
● Scenario and schema
● Rails collection_radio_buttons
● Rails solution
● Rails + SCSS + JS solution
● Links
Scenario and schema
Scenario
A typical context that needs multiple radio button options on a single page
● Multiple users adding review feedback
● Multiple things to be reviewed
Example sites with these capabilities
● TripAdvisor
○ Hotels
○ Restaurants
● GoodReads
○ Books
Book Review Schema
Note to self: review join table architecture
Rails collection_radio_buttons
<input type="radio" value="2" name="user[books_user][score]" id="user_books_user_score_2">
Rails collection_radio_buttons
Rails provides a helper, collection_radio_buttons
<%= @books.each do |book| %>
<%= f.fields_for book.books_users.create do |ff| %>
<%= f.collection_radio_buttons( :score, BooksUser.scores, :id) %>
<% end %>
<% end %>
https://apidock.com/rails/v4.0.2/ActionView/Helpers/FormOptionsHelper/collection_radio_buttons
Rails solution
View
<%= form_for(@user, html: { method: :put }) do |f| %>
...
<% @books.each do |book| %>
<%= f.fields_for "books_user][#{book.id}" do |ff| %>
<%= ff.collection_radio_buttons :score, BooksUser.scores, :last, :last do |rb| %>
<span title=<%= rb.object[0].humanize %>><%= rb.radio_button %></span>
<% end %>
...
Put > update
Build hidden field
Use span for inline
Chrome debugger > elements tab
Chrome debugger > network tab > form data
Form param syntax - best practice?
Is the param syntax correct / best practice?
● I have no idea
User[books_user][4][score] or User[books_user][user_id][4][score] or … ?
● Possible to build any syntax you want
● As built:
○ Succinct
○ Straightforward to parse in the controller
Controller
def update
book_params[:books_user].each do |param|
next unless param.last[:score]&.present?
BooksUser.create(user_id: @user.id, score: param.last[:score].to_i,
book_id: param.first.to_i)
end
redirect_to user_path(@user)
end
def book_params
params.require(:user).permit(books_user: :score)
end
View / controller - best practice?
Is it correct / best practice to use edit / put / update?
● I have no idea
The controller code creates join entries
● Natural fit would be new / post / create, BUT
● Create optimised for single create, not multiple
● Both the books and the user already exist
○ We’re only gluing them together with a join table entry
Rails + SCSS + JS solution
(without collection_radio_buttons)
View
<% @books.each do |book| %>
<%= f.fields_for "books_user][#{book.id}" do |ff| %>
<td class=”book-score” book=<%= book.id %>>
<!-- CSS uses right-to-left, so star index is reversed, ie from 4 to 0 -->
<% star_index = 4 %>
<% 5.times do %>
<span class=”icon” onClick=”clickStar()” score=<%= star_index
%>></span>
<% star_index -= 1 %>>
<% end %>
...
Stash the book id for JS to find
JS entry point
SCSS
.book-score {
unicode-bidi: bidi-override;
direction: rtl;
}
.icon.scored:before, .icon.scored ~ span:before,
.icon.hover:before, .icon.hover ~ span:before {
content: “f005”
color: steelblue;
}
Apologies for missing credit
https://www.w3docs.com/snippets/css/what-does-the-css-tilde-selector-mean.html
JS
function clickStar() {
var name = “user[books_user][“ + bookId + “][score]”
var input = document.createElement(“input”)
input.setAttribute(“type, “hidden”, “name”, name, “value”, score)
oldScore.classList.remove(“scored”)
event.target.classList.toggle(“scored”)
}
Links
Links
Collection radio buttons
https://apidock.com/rails/v4.0.2/ActionView/Helpers/FormOptionsHelper/collection_radio_buttons
Githup repo (public)
https://github.com/egglestn/multiple
Heroku live demo
https://multiple-radio-buttons.herokuapp.com/

More Related Content

What's hot

莫守成規:哈佛教授教你跳出框架、避開慣性陷阱,工作與生活都更出色
莫守成規:哈佛教授教你跳出框架、避開慣性陷阱,工作與生活都更出色莫守成規:哈佛教授教你跳出框架、避開慣性陷阱,工作與生活都更出色
莫守成規:哈佛教授教你跳出框架、避開慣性陷阱,工作與生活都更出色cwbook
 
さるでも分かりたい9dofで作るクォータニオン姿勢
さるでも分かりたい9dofで作るクォータニオン姿勢さるでも分かりたい9dofで作るクォータニオン姿勢
さるでも分かりたい9dofで作るクォータニオン姿勢ytanno
 
すごい配列楽しく学ぼう
すごい配列楽しく学ぼうすごい配列楽しく学ぼう
すごい配列楽しく学ぼうxenophobia__
 
Deterministic Signal
Deterministic SignalDeterministic Signal
Deterministic SignalPei-Che Chang
 
Design and Implementation of GCC Register Allocation
Design and Implementation of GCC Register AllocationDesign and Implementation of GCC Register Allocation
Design and Implementation of GCC Register AllocationKito Cheng
 
Forced Vibrations Project
Forced Vibrations ProjectForced Vibrations Project
Forced Vibrations ProjectMark Falcone
 
「リア充」で学ぶ線形計画問題(ver0.5.3)
「リア充」で学ぶ線形計画問題(ver0.5.3)「リア充」で学ぶ線形計画問題(ver0.5.3)
「リア充」で学ぶ線形計画問題(ver0.5.3)Takeshi Nagae
 
図と実装で理解する『木構造入門』
図と実装で理解する『木構造入門』図と実装で理解する『木構造入門』
図と実装で理解する『木構造入門』Proktmr
 
Cs6702 graph theory and applications 2 marks questions and answers
Cs6702 graph theory and applications 2 marks questions and answersCs6702 graph theory and applications 2 marks questions and answers
Cs6702 graph theory and applications 2 marks questions and answersappasami
 
Or seminar2011final
Or seminar2011finalOr seminar2011final
Or seminar2011finalMikio Kubo
 

What's hot (20)

莫守成規:哈佛教授教你跳出框架、避開慣性陷阱,工作與生活都更出色
莫守成規:哈佛教授教你跳出框架、避開慣性陷阱,工作與生活都更出色莫守成規:哈佛教授教你跳出框架、避開慣性陷阱,工作與生活都更出色
莫守成規:哈佛教授教你跳出框架、避開慣性陷阱,工作與生活都更出色
 
さるでも分かりたい9dofで作るクォータニオン姿勢
さるでも分かりたい9dofで作るクォータニオン姿勢さるでも分かりたい9dofで作るクォータニオン姿勢
さるでも分かりたい9dofで作るクォータニオン姿勢
 
すごい配列楽しく学ぼう
すごい配列楽しく学ぼうすごい配列楽しく学ぼう
すごい配列楽しく学ぼう
 
06. graph mining
06. graph mining06. graph mining
06. graph mining
 
一般グラフの最大マッチング
一般グラフの最大マッチング一般グラフの最大マッチング
一般グラフの最大マッチング
 
Beta gamma functions
Beta gamma functionsBeta gamma functions
Beta gamma functions
 
Lispでやる記号微分
Lispでやる記号微分Lispでやる記号微分
Lispでやる記号微分
 
Coqチュートリアル
CoqチュートリアルCoqチュートリアル
Coqチュートリアル
 
Deterministic Signal
Deterministic SignalDeterministic Signal
Deterministic Signal
 
Problem Set 1
Problem Set 1Problem Set 1
Problem Set 1
 
Design and Implementation of GCC Register Allocation
Design and Implementation of GCC Register AllocationDesign and Implementation of GCC Register Allocation
Design and Implementation of GCC Register Allocation
 
Forced Vibrations Project
Forced Vibrations ProjectForced Vibrations Project
Forced Vibrations Project
 
Functional analysis
Functional analysis Functional analysis
Functional analysis
 
「リア充」で学ぶ線形計画問題(ver0.5.3)
「リア充」で学ぶ線形計画問題(ver0.5.3)「リア充」で学ぶ線形計画問題(ver0.5.3)
「リア充」で学ぶ線形計画問題(ver0.5.3)
 
図と実装で理解する『木構造入門』
図と実装で理解する『木構造入門』図と実装で理解する『木構造入門』
図と実装で理解する『木構造入門』
 
Matlab integration
Matlab integrationMatlab integration
Matlab integration
 
Cs6702 graph theory and applications 2 marks questions and answers
Cs6702 graph theory and applications 2 marks questions and answersCs6702 graph theory and applications 2 marks questions and answers
Cs6702 graph theory and applications 2 marks questions and answers
 
Or seminar2011final
Or seminar2011finalOr seminar2011final
Or seminar2011final
 
Matlab
MatlabMatlab
Matlab
 
Cartesian Closed Category
Cartesian Closed CategoryCartesian Closed Category
Cartesian Closed Category
 

Similar to Multiple radio buttons

Where's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsWhere's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsEleanor McHugh
 
Engines: Team Development on Rails (2005)
Engines: Team Development on Rails (2005)Engines: Team Development on Rails (2005)
Engines: Team Development on Rails (2005)lazyatom
 
Boston Computing Review - Ruby on Rails
Boston Computing Review - Ruby on RailsBoston Computing Review - Ruby on Rails
Boston Computing Review - Ruby on RailsJohn Brunswick
 
How to disassemble one monster app into an ecosystem of 30
How to disassemble one monster app into an ecosystem of 30How to disassemble one monster app into an ecosystem of 30
How to disassemble one monster app into an ecosystem of 30fiyuer
 
Creating effective ruby gems
Creating effective ruby gemsCreating effective ruby gems
Creating effective ruby gemsBen Zhang
 
Tableau course curriculum
Tableau course curriculumTableau course curriculum
Tableau course curriculumMadhukar Reddy
 
Vancouver League of Drupallers - Remembering the User (August 2008)
Vancouver League of Drupallers - Remembering the User (August 2008)Vancouver League of Drupallers - Remembering the User (August 2008)
Vancouver League of Drupallers - Remembering the User (August 2008)baronmunchowsen
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to DjangoJames Casey
 
SF Elixir Meetup - RethinkDB
SF Elixir Meetup - RethinkDBSF Elixir Meetup - RethinkDB
SF Elixir Meetup - RethinkDBPeter Hamilton
 
REST APIs in Laravel 101
REST APIs in Laravel 101REST APIs in Laravel 101
REST APIs in Laravel 101Samantha Geitz
 
Create an application with ember
Create an application with ember Create an application with ember
Create an application with ember Chandra Sekar
 
PostgreSQL Materialized Views with Active Record
PostgreSQL Materialized Views with Active RecordPostgreSQL Materialized Views with Active Record
PostgreSQL Materialized Views with Active RecordDavid Roberts
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”apostlion
 
Introduction to Shiny for building web apps in R
Introduction to Shiny for building web apps in RIntroduction to Shiny for building web apps in R
Introduction to Shiny for building web apps in RPaul Richards
 
Jasig Rubyon Rails
Jasig Rubyon RailsJasig Rubyon Rails
Jasig Rubyon RailsPaul Pajo
 
MongoDB hearts Django? (Django NYC)
MongoDB hearts Django? (Django NYC)MongoDB hearts Django? (Django NYC)
MongoDB hearts Django? (Django NYC)Mike Dirolf
 

Similar to Multiple radio buttons (20)

Where's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsWhere's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord Migrations
 
Schema plus
Schema plusSchema plus
Schema plus
 
Engines: Team Development on Rails (2005)
Engines: Team Development on Rails (2005)Engines: Team Development on Rails (2005)
Engines: Team Development on Rails (2005)
 
Rails vu d'un Javaiste
Rails vu d'un JavaisteRails vu d'un Javaiste
Rails vu d'un Javaiste
 
Boston Computing Review - Ruby on Rails
Boston Computing Review - Ruby on RailsBoston Computing Review - Ruby on Rails
Boston Computing Review - Ruby on Rails
 
How to disassemble one monster app into an ecosystem of 30
How to disassemble one monster app into an ecosystem of 30How to disassemble one monster app into an ecosystem of 30
How to disassemble one monster app into an ecosystem of 30
 
Creating effective ruby gems
Creating effective ruby gemsCreating effective ruby gems
Creating effective ruby gems
 
Tableau course curriculum
Tableau course curriculumTableau course curriculum
Tableau course curriculum
 
Vancouver League of Drupallers - Remembering the User (August 2008)
Vancouver League of Drupallers - Remembering the User (August 2008)Vancouver League of Drupallers - Remembering the User (August 2008)
Vancouver League of Drupallers - Remembering the User (August 2008)
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
SF Elixir Meetup - RethinkDB
SF Elixir Meetup - RethinkDBSF Elixir Meetup - RethinkDB
SF Elixir Meetup - RethinkDB
 
REST APIs in Laravel 101
REST APIs in Laravel 101REST APIs in Laravel 101
REST APIs in Laravel 101
 
Elastic tire demo
Elastic tire demoElastic tire demo
Elastic tire demo
 
Create an application with ember
Create an application with ember Create an application with ember
Create an application with ember
 
PostgreSQL Materialized Views with Active Record
PostgreSQL Materialized Views with Active RecordPostgreSQL Materialized Views with Active Record
PostgreSQL Materialized Views with Active Record
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”
 
Introduction to Shiny for building web apps in R
Introduction to Shiny for building web apps in RIntroduction to Shiny for building web apps in R
Introduction to Shiny for building web apps in R
 
Jasig Rubyon Rails
Jasig Rubyon RailsJasig Rubyon Rails
Jasig Rubyon Rails
 
GHC
GHCGHC
GHC
 
MongoDB hearts Django? (Django NYC)
MongoDB hearts Django? (Django NYC)MongoDB hearts Django? (Django NYC)
MongoDB hearts Django? (Django NYC)
 

Recently uploaded

Science&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfScience&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfjimielynbastida
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024BookNet Canada
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Unlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsUnlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsPrecisely
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentationphoebematthew05
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 

Recently uploaded (20)

Science&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfScience&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdf
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
The transition to renewables in India.pdf
The transition to renewables in India.pdfThe transition to renewables in India.pdf
The transition to renewables in India.pdf
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Unlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsUnlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power Systems
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentation
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 

Multiple radio buttons

  • 1. Multiple radio buttons Aka join table nightmares
  • 2. Multiple radio buttons ● Scenario and schema ● Rails collection_radio_buttons ● Rails solution ● Rails + SCSS + JS solution ● Links
  • 4. Scenario A typical context that needs multiple radio button options on a single page ● Multiple users adding review feedback ● Multiple things to be reviewed Example sites with these capabilities ● TripAdvisor ○ Hotels ○ Restaurants ● GoodReads ○ Books
  • 5. Book Review Schema Note to self: review join table architecture
  • 7. <input type="radio" value="2" name="user[books_user][score]" id="user_books_user_score_2">
  • 8. Rails collection_radio_buttons Rails provides a helper, collection_radio_buttons <%= @books.each do |book| %> <%= f.fields_for book.books_users.create do |ff| %> <%= f.collection_radio_buttons( :score, BooksUser.scores, :id) %> <% end %> <% end %> https://apidock.com/rails/v4.0.2/ActionView/Helpers/FormOptionsHelper/collection_radio_buttons
  • 10.
  • 11. View <%= form_for(@user, html: { method: :put }) do |f| %> ... <% @books.each do |book| %> <%= f.fields_for "books_user][#{book.id}" do |ff| %> <%= ff.collection_radio_buttons :score, BooksUser.scores, :last, :last do |rb| %> <span title=<%= rb.object[0].humanize %>><%= rb.radio_button %></span> <% end %> ... Put > update Build hidden field Use span for inline
  • 12. Chrome debugger > elements tab
  • 13. Chrome debugger > network tab > form data
  • 14. Form param syntax - best practice? Is the param syntax correct / best practice? ● I have no idea User[books_user][4][score] or User[books_user][user_id][4][score] or … ? ● Possible to build any syntax you want ● As built: ○ Succinct ○ Straightforward to parse in the controller
  • 15. Controller def update book_params[:books_user].each do |param| next unless param.last[:score]&.present? BooksUser.create(user_id: @user.id, score: param.last[:score].to_i, book_id: param.first.to_i) end redirect_to user_path(@user) end def book_params params.require(:user).permit(books_user: :score) end
  • 16. View / controller - best practice? Is it correct / best practice to use edit / put / update? ● I have no idea The controller code creates join entries ● Natural fit would be new / post / create, BUT ● Create optimised for single create, not multiple ● Both the books and the user already exist ○ We’re only gluing them together with a join table entry
  • 17. Rails + SCSS + JS solution (without collection_radio_buttons)
  • 18.
  • 19. View <% @books.each do |book| %> <%= f.fields_for "books_user][#{book.id}" do |ff| %> <td class=”book-score” book=<%= book.id %>> <!-- CSS uses right-to-left, so star index is reversed, ie from 4 to 0 --> <% star_index = 4 %> <% 5.times do %> <span class=”icon” onClick=”clickStar()” score=<%= star_index %>></span> <% star_index -= 1 %>> <% end %> ... Stash the book id for JS to find JS entry point
  • 20. SCSS .book-score { unicode-bidi: bidi-override; direction: rtl; } .icon.scored:before, .icon.scored ~ span:before, .icon.hover:before, .icon.hover ~ span:before { content: “f005” color: steelblue; } Apologies for missing credit https://www.w3docs.com/snippets/css/what-does-the-css-tilde-selector-mean.html
  • 21. JS function clickStar() { var name = “user[books_user][“ + bookId + “][score]” var input = document.createElement(“input”) input.setAttribute(“type, “hidden”, “name”, name, “value”, score) oldScore.classList.remove(“scored”) event.target.classList.toggle(“scored”) }
  • 22. Links
  • 23. Links Collection radio buttons https://apidock.com/rails/v4.0.2/ActionView/Helpers/FormOptionsHelper/collection_radio_buttons Githup repo (public) https://github.com/egglestn/multiple Heroku live demo https://multiple-radio-buttons.herokuapp.com/