ROR HABTM implementation with simple forms - ruby-on-rails

I am trying to implement HABTM model with two of my database tables. Two tables are Users and Ratings. According to general structure I should have following things
Users Model/Table
Ratings Model/Table
User_ratings Table
But User_ratings will have an extra column other than two ids and that will be a pre-defined string named stage. Stage will have pre-defined values such as appointment, completion e.t.c.
My first question is does this change the role of my middle table (through table) or will we still create just a migration for middle table.
Secondly, I am trying to implement a simple form to assign different users different ratings and my code looks like.
= simple_form_for #appointment, :html => {:class => 'form-horizontal'} do |f|
= f.input :start_datetime, as: :datetime_picker, input_html: {class: "datetime form-control"}
= f.input :end_datetime, as: :datetime_picker, input_html: {class:"datetime form-control"}
/ Now here I want three fields belonging to my middle table. Something like
= r.input :contact_id, :collection => Contact.all, :label_method => :get_contacts
= r.inout :rating_id, :collection => Rating.all, :label_method => :get_ratings
= r.hidden_field :stage, value: 'Appointment'
The problem here is that I don't have a model for middle table and hence I am stuck with how to do it with simple_form
Any kind of help will be highly appreciated. Thanks

Related

Rails simple_form check_boxes save multiple selections to database

I'm trying to have a list to checkboxes with multiple selection. I have this array in the model.
QOL = ["your health",
"your stress levels",
"how safe you feel",
"your education",
"your home"
]
I'm trying to do somthing like this in my simple_form form.
<%= f.input :qolselections, as: :check_boxes, :collection => Goal::QOL %>
How can I save the selections to the database and be able to retrieve them as the selected string values?
Instead of a Constant, you should consider an enum:
class YourModel < ActiveRecord::Base
enum qol_selection: ["your health", "your stress levels", "how safe you feel", "your education", "your home"]
end
Then, your solution becomes similart to the one described in the following question Saving enum from select in Rails 4.1 (https://stackoverflow.com/a/23686698/637094):
f.input :qol_selection, :as => :select, :collection => YourModel.qol_selections.keys.to_a

Money Rails Gem - null values

I have monetised two models of my Rails 4 app with Money-Rails gem.
One is called Participants, the other is called Funding. Each of these models is nested inside another model, called Scope. Scope belongs to Project.
The associations are:
Project has one Scope; Scope belongs to Project
Scope has one Participant and has one funding; each of Participant and Funding belong to Scope.
Project accepts nested attributes for Scope. Scope accepts nested attributes for Participant and Funding.
Params for each relevant attribute in Participant and Funding are permitted in the Scope and Project Controllers as well as the models themselves. Params for Scope are permitted in the Scope and Project controllers.
In my Project form, I ask several questions. That form also has nested forms for each of the models which belong to it. Inside the Scope form, I ask users two boolean questions, being: Do you want participants? Do you want funding? Each of these models has a follow up question about participation cost and funding (those attributes are monetised).
If the answer to those questions is true, then I reveal the participant or funding form partial and ask how much money they want.
I have two problems:
First problem: Not null violation
1. If a user says they do want participants, but there is no associated costs, so that the boolean question inside the participant model asking whether there is cost involved with participation, I get an error that says:
ERROR: null value in column "participation_cost_pennies" violates not-null constraint
If a user says they don't want participants in answer to the question asked in the Scope form, I get the same error as in 1 above
Second problem: If I save an amount in the monetised fields, and come back to edit the project form, the form does not show the saved amount in the monetised field - and if you don't reenter it, I get an error saying that it can't be blank.
Does anyone know how to:
make the first problem go away in all circumstances except those when participation costs are actually sought; and
Fix the second problem by displaying the original amount saved when you come back to edit the form? I have tried inserting :selected into my form element, but it doesn't do anything.
My code is as follows:
Inside my Scope form (nested inside my project form):
<%= f.simple_fields_for :scope do |s_all| %>
<%= s_all.input :if_participant, :as => :boolean, :label => false, inline_label: 'Public participants or volunteers' %>
<%= s_all.input :if_funding, :as => :boolean, :label => false, inline_label: 'Funding or expenses' %>
If the answer to these fields is true, then I reveal the partial forms for participant of funding (for whichever is true).
Inside my Participants partial form, I have:
<%= f.simple_fields_for :scope do |participants_s| %>
<%= participants_s.simple_fields_for :participant do |par| %>
<%= f.label 'Are participants reimbursed for their costs?', :class => 'question-project' %>
<%= par.collection_radio_buttons :costs, [[true, ' Yes'], [false, ' No']], :first, :last, {:item_wrapper_class => 'fixradio'}, {:class => "response-project"} %>
<%= f.label 'What amount will you pay for participation costs?', :class => 'question-project' %>
<%= par.select :participation_cost_currency,
options_for_select(major_currencies(Money::Currency.table)), selected: :participation_cost_currency,
label: false,
prompt: "Select your costs currency" %>
<%= par.input :participation_cost, label: false, placeholder: 'Whole numbers only', selected: :participation_cost_pennies, :input_html => {:style => 'width: 250px; margin-top: 20px', class: 'response-project'} %>
For the first problem, you'll want to set a default value for the participation_cost_cents column in a migration:
# in console
> rails g migration change_default_for_participation_cost_cents
# in migration file
class ChangeDefaultForParticipationCostCents < ActiveRecord::Migration
def change
change_column :participants, :participation_cost_cents, :integer, default: 0
end
end
I'm not sure I follow on the second problem though. Maybe you should split the question in two?
A meetup group for Rails has helped me answer this question. The answer is not obvious - especially for newcomers.
My problem was I had an attribute in my database called participation_cost. Monetise then tried to make a method with the same name and that was failing because of the attribute in my table. For others, you don't need the attribute in your database with the name of the field you want to monetise.
Removing that attribute (in my case, participation_cost) solved my problem.

Create a drop down menu using a Table Attribute in Rails Active Admin

I need to create a dropdown field(membership_code), whose values are contained on a different table called members.
Schema
prereg
id
membership_code(string) not a foreign key
verification_code
members
id
membership_code
Prereg Active Admin Model
ActiveAdmin.register Prereg do
form do |f|
f.inputs "Preregistered Users" do
f.input :verification_code
f.input :email
#THIS LINE NEEDS TO BE CHANGED TO LIST DOWN THE MEMBERSHIP_CODE FROM MEMBERS
# f.input :membership_code, :as => :select, :collection => Members.all()
end
f.actions
end
To add, I was planning to have this logic wherein whenever you create a Prereg record, the selected "membership_code" would be deleted from the members.membership_code list.
How is this done in ActiveAdmin? Sorry I haven't found any good resource for DB Hooks and I'm still new to Rails.
I think you are looking for something as follows:
f.input :membership_code, as: :select, collection: Member.all.map(&:membership_code)
try this
f.input :membership_code, :as => :select, :collection => Members.select(:membership_code)
Thanks

Collection select with many-to-many in same model in rails gives error

I have a weird rails database/form problem.
I got 1 table with Courses, and 1 table Prerequisites, which has 2 columns that both hold Course_ids (columns are called "course_a_id" and "course_b_id").
In the Course model I have this:
:has_and_belongs_to_many(:prerequisites,
:join_table => "prerequisites",
:foreign_key => "course_a_id",
:association_foreign_key => "course_b_id",
:class_name => "Course")
From this SO answer
This works if I put the prerequisites in by Console, something like this:
Course.find(3).prerequisites = [Course.find(1), Course.find(2)]
This form field however does not let me put prereqs in the DB:
<%= f.label :prerequisite, "Prerequisites" %>
<%= f.collection_select(:prerequisites, Course.all, :id, :name,
{:multiple => true}, :multiple => "multiple") %>
Gives this error after posting with one option selected with value 1:
"Course(#-631146998) expected, got String(#77208170)"
and in the parameter dump:
"prerequisites"=>["",
"1"]}
I have no clue how that "" ended up in the params and can't figure out another way to create the form field. I think my model is set up correctly.

Ruby on rails, split a big form into separate smaller forms

Could not find the answer to the question on how to split forms in rails in multiple smaller forms.
Say you have a big form with
firstname
lastname
gender
age
email
country
city
state
I have a validate_presence for all these fields. So when I create several forms like:
= simple_form_for #profile, :wrapper => :inline do |f|
= f.label "firstname"
= f.select :firstname
without all the values from the top list (first name,last name,etc) I get errors because the splitter form does not contain those values and they need to be present at first to make this work at all.
What would be a good way to have several forms but with only a portion of the values and update them without getting the issue described above?
If you want the ability to update pieces of the model then you need to split the validations into pieces as well.
One way to do it is to have a virtual attribute in your model that gets set by a hidden field in each form. E.g you may have a form:
= simple_form_for #profile, :wrapper => :inline do |f|
= f.hidden :form, :input_html => {:value => 'names'}
= f.label "firstname"
= f.select :firstname
Then in your model:
class Profile
attr_accessor :form
validates :firstname, :presence => true, :if => lambda { |o| o.form == "names" }
end
The validation will run only if the change was submitted from the right form.
Check out conditional validation guide: http://guides.rubyonrails.org/active_record_validations_callbacks.html#conditional-validation for more details.
Other way is a multistep form as suggested by apneadiving: http://railscasts.com/episodes/217-multistep-forms This uses the same technique as in the first example by having a current_step attribute, but the progression is linear.
You're asking for a multi step form I guess.
Look at this screencast, you'll find conditional validations which are the way to proceed.

Resources