ActiveAdmin update two models in one form - ruby-on-rails

I have an ActiveAdmin page to edit Loan info, like that:
ActiveAdmin.register Loan do
...
form do |f|
f.inputs 'Loan' do
f.input :name
f.input :amount
end
f.actions
end
(I'm omitting lot of fields for clarity)
Now, due to performance reasons I extracted amount field to LoanDetails model that has one-to-one relation with Loan
class Loan < ActiveRecord::Base
...
has_one :details, class_name: 'LoanDetails', foreign_key: :loan_id
...
end
class LoanDetails < ActiveRecord::Base
...
belongs_to :loan
...
end
This change brakes ActiveAdmin page. Attempt to edit loan results in
unknown attribute 'amount' for Loan.
error.
How can I update my ActiveAdmin to work properly with new data structure?

My colleague helped me to solve this while I was in the middle of writing StackOverflow question.
ActiveAdmin.register Loan do
...
form do |f|
f.inputs 'Loan' do
f.input :name
end
f.inputs 'Loan Details', for: [:details, f.object.details] do |d|
d.input :amount
end
f.actions
end
end

Related

Rails nested form with unknown columns

I'm creating an admin interface where the admin (of a company) can add custom fields to their employees.
Example:
Models:
Employee: Basic info like name, contact info, etc (has_many employee_field_values)
EmployeeFields: These are the dynamic ones the admin can add (every company has different needs, it could be anything), lets say favorite_food
EmployeeFieldValues: The actual values based on the fields above, say pizza (belongs_to both models above)
What's a smart way of adding the EmployeeFieldValues fields while editing an employee?
I'm trying something simple like this, but not sure if I like it
# Controller
#custom_fields = EmployeeFields.all
# View
<%= form_for(#employee) do |f| %>
<%= f.text_field :first_name %>
<% #custom_fields.each do |custom_field| %>
<%= custom_field.name %>
<%= text_field_tag "employee_field_values[#{custom_field.name}]" %>
<% end %>
<%= f.submit :save %>
<% end %>
And then when updating, params[:employee_field_values] gives this:
<ActionController::Parameters {"favorite_food"=>"pizza"}>
So, not sure if this is a good direction, also I'm not sure how to handle future edits to an employee's custom_fields if they change.
I think it will be better to use EmployeeField as nested model and EmployeeFieldValue for select field.
For example:
Models
class Employee < ActiveRecord::Base
validates :name, presence: true
has_many :employee_field_values
accepts_nested_attributes_for :employee_field_values, reject_if: ->(x) { x[:value].blank? }
end
class EmployeeFieldValue < ActiveRecord::Base
belongs_to :employee
belongs_to :employee_field
end
class EmployeeField < ActiveRecord::Base
has_many :employee_field_values, inverse_of: :employee_field, dependent: :destroy
validates :title, presence: true, uniqueness: true
end
Controller
class EmployeesController < ApplicationController
def new
#employee = Employee.new
#employee.employee_field_values.build
end
end
View
= simple_form_for #employee, url: '/' do |f|
= f.input :name
= f.simple_fields_for :employee_field_values do |ff|
= ff.input :value
= ff.input :employee_field_id, collection: EmployeeField.all.map{|x| [x.title, x.id]}
Also you need to make buttons for adding/removing :employee_field_value, and you can do it with gem cocoon for example
OR you can build all objects in controller(for each EmployeeField) and do without select box

Activeadmin Formtastic custom input

I have a simple app, which has three models Assessment, Question and AssessmentQuestion
In Assessment i have the association like,
class Assessment < ActiveRecord::Base
has_many :assessment_questions, dependent: :destroy
has_many :questions, through: :assessment_questions
end
In Question i have,
class Question < ActiveRecord::Base
has_many :assessment_questions, dependent: :destroy
has_many :bank_questions, dependent: :destroy
end
In AssessmentQuestion i have,
class AssessmentQuestion < ActiveRecord::Base
belongs_to :question
belongs_to :assessment
end
assessment_questions table has :assessment_id, :question_id and :mark columns
I have admin interface using ActiveAdmin gem.
While creating assessments in admin interface, In admin/assessment.rb i have a form generated by the formtastic gem,
form do |f|
f.inputs do
f.input :name
f.input :duration
f.input :questions, as: :check_boxes, member_label: :id
f.input :creator_id
end
f.actions :commit
end
This looks fine and no problem. The thing that i want is while choosing questions through the checkboxes, i want a textbox below or side to each checkbox containing mark of the questions will be filled in text boxes respectively ( through question.assessment_question.mark association ), so that i can edit the prefilled marks of the questions while creating assessment or leave it as it is.
I have tried, but got some error like
undefined method `to_sym' for {:for=>:questions}:Hash
My code,
form do |f|
f.inputs do
f.input :name
f.input :duration
f.input for: :questions do | question |
f.input :question, as: :select
f.input question.assessment_question.mark
end
f.input :creator_id
end
f.actions :commit
end
Any solutions?
Finally, i figured it out.
I actually created a custom semantic_form_for form _form.html.erb as a partial and included this in admin/assessment.rb file
form partial: 'assessment/form'
That's how i solved.
Reference: http://activeadmin.info/docs/5-forms.html
I would make a custom input that contains a checkbox and a string input:
https://github.com/justinfrench/formtastic#modified--custom-inputs
The solution is obvious, your "f.input :for" misses an "s".
It should be f.inputs

Mass assignment error with polymorphic association

I'm getting a mass assignment error when submitting a nested form for a has_one polymorphic model. The form is trying to create Employee and Picture instances based on the polymorphic association Rails guide.
I would appreciate literally ANY functioning example of a nested creation form for a has_one polymorphic model! I know there are tons of questions on mass assignment errors but I've never seen a working example with polymorphic associations.
Models
class Picture < ActiveRecord::Base
belongs_to :illustrated, :polymorphic => true
attr_accessible :filename, :illustrated
end
class Employee < ActiveRecord::Base
has_one :picture, :as => :illustrated
accepts_nested_attributes_for :picture
attr_accessible :name, :illustrated_attribute
end
Migrations
create_table :pictures do |t|
t.string :filename
t.references :illustrated, polymorphic: true
end
create_table :employees do |t|
t.string :name
end
controllers/employees_controller.rb
...
def new
#employee = Employee.new
#employee.picture = Picture.new
end
def create
#employee = Employee.new(params[:employee])
#employee.save
end
...
Error
Can't mass-assign protected attributes: illustrated
app/controllers/employees_controller.rb:44:in `create'
{"utf8"=>"✓", "authenticity_token"=>"blah"
"employee"=>{"illustrated"=>{"filename"=>"johndoe.jpg"},
"name"=>"John Doe"},
"commit"=>"Create Employee"}
In the models, I've tried every permutation of :illustrated, :picture, :illustrated_attribute, :illustrated_attributes, :picture_attribute, :picture_attributes, etc. Any tips or examples?
EDIT:
_form.html.erb
<%= form_for(#employee) do |f| %>
<%= f.fields_for :illustrated do |form| %>
<%= form.text_field :filename %>
<% end %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
You need to specify the nested_attributes appropriately. accepts_nested_attributes_for takes the name of the association as parameter and then you need to add the same assoc_attributes to your attr_accessible. So change your Employee model to
class Employee < ActiveRecord::Base
has_one :picture, :as => :illustrated
accepts_nested_attributes_for :picture
attr_accessible :name, :picture_attribute
end
And change the field_for line in the view code to
<%= f.fields_for :picture do |form| %>

How to setup a deeply nested form in Rails 3.2

I'm trying to build a rather complex nested form in rails and am stuck.
Basically, I have three models - Applicant, DataPoint, ApplicantDataPointValue .
The user can create a new DataPoint, give it a name ("gender" etc.) select it's type ("string","integer" etc.). The type determines what column the data will eventually be saved in in the ApplicantDataPointValue table.
I then want the user, when they're creating a new Applicant, to be able to add a value for each DataPoint into the ApplicantDataPointValue table
My models look like the following:
Applicant:
class Applicant < ActiveRecord::Base
has_many :applicant_data_point_values, dependent: :destroy
has_many :data_points, :through => :applicant_data_point_values
accepts_nested_attributes_for :data_points
accepts_nested_attributes_for :applicant_data_point_values
attr_accessible :data_points_attributes, :applicant_data_point_values_attributes
end
DataPoint:
class DataPoint < ActiveRecord::Base
has_many :applicant_data_point_values
has_many :applicants, :through => :applicant_data_point_values
accepts_nested_attributes_for :applicant_data_point_values
end
ApplicantDataPointValue:
class ApplicantDataPointValue < ActiveRecord::Base
belongs_to :data_point
belongs_to :applicant
end
But I'm at a loss to what to do in the 'new' and 'create' sections of my controller or how to construct the form.
Any insight would be greatly appreciated.
From what I understand, the form for the User will also have multiple ApplicantDataPointValue fields. (but that form won't allow creating of new DataPoint fields, right?)
In the controller new action, you'll want to set up your model with associated data point values:
def new
#user = User.new
DataPoint.all.each do |data_point|
applicant_data_point_value = #user.applicant_data_point_values.build
applicant_data_point_value.data_point = data_point
end
end
And then, display a text box for each data point value.
<%= form_for #user do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<% #user.applicant_data_point_values.each do |data_point_value| %>
<%= f.fields_for :applicant_data_point_values, data_point_value do |fields| %>
<%= fields.label :value, data_point_value.data_point.type %>
<%= fields.text_field :value %>
<% end %>
<% end %>
Reference: http://railscasts.com/episodes/196-nested-model-form-part-1

How to nest a parent form in its child form?

I have a Rails app in which users can post vacancies. If the user is new, he or she can fill out the vacancy form first, and than add their company and register at the end of the project. I made a pretty nice multistep form, but now I want to nest the company and registration form in the vacancy form, and I can't get it done. There are several related posts but none of the solutions offered seem to fit my situation.
Here's what I have:
class Vacancy < ActiveRecord::Base
attr_accessible :type, :function, :address, :description, :requirements, :address_attributes, :field_ids
attr_writer :current_step
belongs_to :company
belongs_to :user
accepts_nested_attributes_for :company
accepts_nested_attributes_for :user
end
Company and User both have a have_many relationship to Vacancy.
How should I do this?
EDIT1
This is the form I'm trying to display:
<%= f.inputs :name => "Bedrijfsgegevens" do %>
<%= f.semantic_fields_for :company do |company| %>
<%= company.input :name %>
<% end %>
<% end %>
EDIT2
The reason I'd rather not transform the form into a User or Company form, nesting the vacancy inside one of these, is that I want the vacancy edit form to be the same as this one, hiding a few of the steps when necessary. This fits the apps flow best.

Resources