How do I add custom attributes to a form_for? - html

Ok, so here is my code.
<%= form_for #quiz do |f|%>
<% #questions.shuffle.each do |q| %>
# get_answers returns an array of 4 random answers
<% answers = q.get_answers %>
<%= f.label q.inquest %><br>
<% answers.each do |a| %>
<%= f.radio_button <need help here!>, a %>
<%= f.label <need help here!>, a %><br>
<%= f.hidden_field <need help here!>, q.id %>
<% end %>
<% end %>
<% end %>
my quiz table has the attributes
concept_id
user_id
how do I add custom attributes that I can have access to in the post action? It should be dynamic so it can scale with how many questions there are. I want something like this for my params.
{
user_answers: {
question1: {
:question_id
:answer
{
}
}
Depending on how many questions there are, it'll go like question1, 2, 3, 4 etc..
The hidden_field would carry with question_id while the radio_button would carry the answer. I don't need it to save or anything, I just need access to them

Ok, so I realized that I shouldn't have called those form tags on f. instead have them as their own form tags
for example:
radio_button_tag instead of f.radio_button

Related

Rails radio_buttons multiple selection for same attribute, is it possible?

I have a search_form_for and I need to be able to select multiple Payment statuses to make a Ransack search.
We already have an f.select dropdown box for this attribute, but we now need to be able to select more than one status at the same time.
form:
<%= search_form_for #search, url: admin_payments_path, html: {class: "form-inline"} do |f| %>
<div class="form-group">
<%= f.select :status_eq, payment_status_selector, { include_blank: "Payment status.."}, class: "form-control gray" %>
</div>
<% end %>
I've tried:
<%= f.select :status_eq, payment_status_selector, {include_blank: false}, {multiple: true, as: :radio_buttons} %>
gives me a select box with all the options allowing me to select multiple, but they are not radio_buttons and an empty value "" is passed along with the selected options.
<% payment_status_selector.each do |status| %>
<%= radio_button_tag :status_eq, "#{status[1]}", false, class: 'radio-checkbox' %>
<%= label_tag( "#{status[0]}") %>
<% end %>
This gives me a radio_button for each possible status, but I can't select more than one.
I can't figure out the correct way to do it. Maybe with check_boxes are a better option to be able to select/unselect statuses?
Yes, using check_box will be a better option.
Try,
<% payment_status_selector.each do |status| %>
<%= f.check_box :payment_statuses, { multiple: true }, status, false %>
<%= label status %>
<% end %>
And you can expect the values in controller from params as:
{ search: { payment_statuses: ["status 1", "status 2"] }
make sure that payment_status_selector returns array of values.
Hope that helped.
Reference: https://medium.com/programming-problem-solving-logbook/rails-multiple-checkboxes-e9c4c7fda356

Hash being saved to database but unable to render its values in Rails forms?

I added a new column to model Plan, named :per_unit_quantities_configuration which is a hash with min, max and step key/values.
t.jsonb "per_unit_quantities_configuration", default: {}
When I edit a Plan, the hash is being correctly saved to the DB (I can access each key/value from the console), but the forms are not displaying any of its values (the fields are empty).
I tried adding a store_accessor for the column in the Plan model, but it is not working:
store_accessor :per_unit_quantities_configuration, :min, :max, :step
Example of a simple_form html that does not display hash values:
<%= simple_form_for [:admin, #base_plan, #plan] do |f| %>
<% if f.object.base_plan.per_unit? %>
<div class="d-flex">
<%= f.simple_fields_for :per_unit_quantities_configuration do |fields| %>
<% if f.object.errors[:per_unit_quantities_configuration].any? %>
<%= f.error :per_unit_quantities_configuration, id: "per_unit_price_error", class: "invalid-feedback", error_prefix: "gato" %>
<% end %>
<%= fields.input :min %>
<%= fields.input :max %>
<%= fields.input :step %>
<% end %>
</div>
<% end %>
<%= f.button :submit, class: "pull-right" %>
<% end %>
What am I doing wrong?
since you setup store_accessor :per_unit_quantities_configuration then you can access directly 3 attributes min, max, step, so that you no need to wrap those attributes on simple_fields_for :per_unit_quantities_configuration and treat them as normal fields (that mean on controller you have to permit them as normal fields)
# view
<%= f.input :min %>
<%= f.input :max %>
<%= f.input :step %>
# controller
def plan_params
params.require(:plan).permit(:min,:max,:step)
end

Ruby on Rails: How do I assign a "step" attribute on a time_field to step in 30 minute intervals?

I'm using form_with to generate a html form using Ruby on Rails. In this form_with, I'm using a fields_for to generate another section of forms that are attributes of the first form.
To make things simple, though, I simply want to know how I can restrict time selections to be in 30 minute increments.
For example, I am doing:
<%= form.fields_for employee_jobs do |assign_job| %>
<%= assign_job.time_field :time_start %>
<%= end %>
How can I make it so I get a "step" attribute in the html time input node when I'm done? Right now, I'm trying to do:
<%= form.fields_for employee_jobs do |assign_job| %>
<%= assign_job.time_field(:time_start, :step=>600) %>
<%= end %>
But it's not giving me the desired result.
I found out what I needed to do. Instead of using a time_field input, you can use the time_select input, and specify steps through the minute_step keyword.
Instead of:
<%= form.fields_for employee_jobs do |assign_job| %>
<%= assign_job.time_field :time_start %>
<%= end %>
You can do:
<%= form.fields_for employee_jobs do |assign_job| %>
<%= assign_job.time_select :time_start {:minute_step => 30} %>
<%= end %>
And this solved my problem.

passing params throught rails forms

I am using rails 4 and have a subject and comment models. Subject is a one to many relationship with comments. I want a simple page that can add comments to many subjects on the same page. So in my form I know how to submit a comment to create but I dont know how to find the right subject in my controller to add it to. Any advice?
class CommentsController < ApplicationController
def create
comment = Comment.create(comment_params)
if comment.save
# The line below is incorrect, I dont know what to do
Subject.find(params[:subject_id]).comments << comment
redirect_to(:controller => 'static_pages', action: 'home')
end
end
def new
end
private
def comment_params
params.require(:comment).permit(:text, :user_name)
end
end
StaticPages#home Find me in
app/views/static_pages/home.html.erb
<% #subjects.each do |subject| %>
<div class="subjects <%= cycle('odd', 'even') %>">
<h1><%= subject.name %></h1>
<h3><%= subject.description %></h3>
<% subject.comments.each do |comment|%>
<div class="comment">
<h4><%= comment.user_name%></h4>
<%= comment.text %>
</div>
<% end %>
<%= form_for(#comment) do |f| %>
<%= f.label :user_name %>
<%= f.text_field :user_name %>
<%= f.label :text %>
<%= f.text_field :text %>
<%= f.submit('Create comment', subject_id: subject.id) %>
<% end %>
</div>
<% end %>
The simplest way would be to populate the subject_id attribute of your #comment form, like this:
<%= form_for(#comment) do |f| %>
<%= f.label :user_name %>
<%= f.text_field :user_name %>
<%= f.label :text %>
<%= f.text_field :text %>
<%= f.hidden_field :subject_id, value: subject.id %>
<%= f.submit('Create comment', subject_id: subject.id) %>
<% end %>
This will populate the subject_id attribute of your new Comment object, which will essentially associate it through Rails' backend:
#app/controllers/your_controller.rb
Class YourController < ApplicationController
def create
#comment = Comment.new comment_params
#comment.save
end
private
def comment_params
params.require(:comment).permit(:subject_id, :text, :user_name)
end
end
--
foreign_keys
This works because of the Rails / relational database foreign_keys structure
Every time you associate two objects with Rails, or another relational database system, you basically have a database column which links the two. This is called a foreign_key, and in your case, every Comment will have the subject_id foreign_key column, associating it with the relevant subject
So you may have many different forms using the same #comment variable - the trick is to populate the foreign_key for each one

Basic rails form, does not deselect alternative options - can't find solution for rails

I have excel, video, and multiple choice boolean columns in my Step model. I am trying to get it so the user has to choose one of the three, and when saved it passes back to the database as true. Right now my two problems are a)when I select one, it doesn't deselect the others and b) the radio button is on a different line than the text that labels it. Any help would be appreciated.
<fieldset class="stepCreator">
<%= "Step" %>
<%= f.label :description, "Description" %>
<%= f.text_field :description %>
<div>
<%= f.label :excel, "Excel" %>
<%= f.radio_button(:excel, true, :checked => true) %>
<%= f.label :video, "Video" %>
<%= f.radio_button(:video, true) %>
<%= f.label :multiple_choice, "Multiple Choice" %>
<%= f.radio_button(:multiple_choice, true) %>
</div>
<%= f.hidden_field :_destroy %>
<%= link_to "remove", '#', class: "btn btn-danger btn-mini remove_fields "%>
</fieldset>
Actually you have 2 very different problems.
All the radio buttons (that you want to select one and automatically deselect the others) must have the same name, and different values, so it should be something like:
f.radio_button(:media, :excel, :checked => true)
f.radio_button(:media, :video)
For the labels to be at the same line as the checkbox, you just have to change the CSS.
From the documentation:
http://guides.rubyonrails.org/form_helpers.html
try:
<%= radio_button_tag(:age, "child") %>
<%= label_tag(:age_child, "I am younger than 21") %>
<%= radio_button_tag(:age, "adult") %>
<%= label_tag(:age_adult, "I'm over 21") %>
radio buttons have to select the same attribute in your model, in this example i selected the age attribute and i can give it 1 of two values, or he is a child or he is an adult
hope it helps