I'm trying to create a form for 'Member' using simple_form and having trouble displaying an association where it display the organization as below instead of the id, or organization_name. Am I missing something here? How should I go about this?
**Organization:0x0000000485cf88
Organization:0x0000000485c948
Organization:0x0000000485c358**
class Organization < ActiveRecord::Base
has_many :members
attr_accessible :organization_name
end
class Member < ActiveRecord::Base
belongs_to :organization
attr_accessible :active, :email, :first_name, :last_name, :role
end
<%= f.input :first_name %>
<%= f.input :last_name %>
<%= f.input :role %>
<%= f.input :email %>
<%= f.input :active %>
<%= f.association :organization %>
<%= f.button :submit %>
Thanks.
Cheers,
Azren
looks like Organization model doesn't have any of these fields: [ :to_label, :name, :title, :to_s ] so SimpleForm can't detect a default label and value methods for collection. I think you should pass it manually.
add to_label function to your Organization class as shown below
class Organization < ActiveRecord::Base
has_many :members
attr_accessible :organization_name
def to_label
"#{organization_name}"
end
end
refered
Simple form association custom label name
Related
I have a form on a model called "Patient", which has_one "Role" via polymorphic association. And the "Role" has_one "User". And I need to modify the "User" field "first_name" via a form...
class Patient < ApplicationRecord
has_one :role, :as => :roleable, dependent: :destroy
accepts_nested_attributes_for :role
end
class Role < ApplicationRecord
belongs_to :user
accepts_nested_attributes_for :user
belongs_to :roleable, polymorphic: true, optional: true
end
class User < ApplicationRecord
has_many :roles
end
class PatientsController < ApplicationController
def show
#patient = Patient.find(params[:id])
# This works just fine, so I know the data is there
puts(#patient.role.user.first_name)
end
end
How do I make a form that includes this field? This is what I have so far that isn't working:
<%= form_for(:patient, url: edit_patient_path(params[:id])) do |f| %>
<%= f.fields_for :role do |r| %>
<%= r.fields_for :user do |u| %>
<%= u.text_field :first_name, value: u.first_name, class: "value", disabled: false %>
<% end %>
<% end %>
<% end %>
But unfortunately this is not working:
undefined method `first_name' for #<ActionView::Helpers::FormBuilder:0x007f82d30c4ad8>
First change your form to <%= form_for(#patient) %> so that it wraps the #patient object.
Use .object to get the object wrapped by the form builder.
<%= u.text_field :first_name, value: u.object.first_name, class: "value", disabled: false %>
But you don't need to explicitly assign the value in the first place and the disabled attribute defaults to false:
<%= u.text_field :first_name, class: "value" %>
I have three models: Course, Category, and Categorisation.
# course.rb
class Course < ApplicationRecord
has_many :categorisations, foreign_key: "course_id", dependent: :destroy
has_many :categories, through: :categorisations
end
#category.rb
class Category < ApplicationRecord
has_many :categorisations, foreign_key: "category_id", dependent: :destroy
has_many :courses, through: :categorisations
end
# categorisation.rb
class Categorisation < ApplicationRecord
belongs_to :course
belongs_to :category
validates :course_id, presence: true
validates :category_id, presence: true
end
Course controller has the following params:
def course_params
params.require(:course).permit(:name, :prerequisite, :description,
:user_id, :category_ids => [])
end
I'm trying to build the association via the Course form:
<%= form_for #course do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :prerequisite %>
<%= f.text_field :prerequisite, class: 'form-control' %>
<%= f.label :description %>
<%= f.text_area :description, class: 'form-control' %>
<%= f.label :category_ids, "Category" %>
<%= f.collection_check_boxes :category_ids, Category.all, :id, :name,
{}, { multiple: true, class: 'form-control'} %>
<%= f.submit "Create a new course", class: "btn btn-primary" %>
<% end %>
However when I click submit I get the validation error:
Categorisations is invalid
I'm unsure why this is the case?
Removing the presence validation on :course_id will fix the issue
class Categorisation < ApplicationRecord
belongs_to :course
belongs_to :category
# validates :course_id, presence: true
validates :category_id, presence: true
end
Problem:
Course is not saved but due to through association when you associate category with course rails first tries to save categorisation but course_id is not available yet
And this is the reason presence validation fails for course_id
Solution
Removing the validation is just a workaround the actual solution will be something interesting
NOTE: Even I am facing the similar issue a few days back. we have removed validation for now. I will be interested in any better solution
You're not able to save any entity that relates to Categorization in database because of presence: true action. Firstly, I think it's a better idea to validate :category_id in the schema.rb by category_id null: false. And secondly, are you sure you need the Categorization model? My suggestion is to think of putting a categorizationable.rb file in your yourApp/app/models/concerns folder and after that using its functionality in the existing models. You can read more about concerns here. This technique is really powerful when your models need refactoring.
I am having trouble trying to update nested models in my form. I don't get any errors and but the attributes don't get updated.
I have the following model:
class Trip < ActiveRecord::Base
has_many :segments
accepts_nested_attributes_for :segments, allow_destroy: true
end
class Segment < ActiveRecord::Base
belongs_to :start_location, class_name: 'Location'
belongs_to :end_location, class_name: 'Location'
belongs_to :trip
validates_presence_of :date, :start_location, :end_location
end
class Location < ActiveRecord::Base
has_many :segments
end
And have this code in the _form.html.erb:
<%= form_for #trip do |f| %>
...
<%= f.fields_for :segments do |builder| %>
<%= render 'segment_fields', f: builder %>
<% end %>
...
<% end %>
And this in the partial _segment_fields.html.erb:
<%= f.collection_select :start_location_id, Location.order(:name), :id, :name %> -
<%= f.collection_select :end_location_id, Location.order(:name), :id, :name %> <br>
<%= f.date_field :date %>
In my controller I also permited the assigment of :segments_attributes
def trip_params
params.require(:trip).permit(:name, :start_date, :end_date, :segments_attributes)
end
Does anybody know what I am lacking or doing wrong?
When you are creating a new record you don't need its id to be permitted as it's not been created but when you want to update your record you need to pass id to the permitted attributes, else it will work with create but not when you want to update your record, so you need to do:
def trip_params
params.require(:trip).permit(:id, :name, :start_date, :end_date, segments_attributes: [:id,:start_location_id,:end_location_id, :date])
end
I am trying to create a drop-down-select menu that users can be selected from. I want to also have the number of projects they are assigned to displayed next to their name
class User < ActiveRecord::Base
attr_accessible :email, :username, :password, :password_confirmation, :remember_me, :first_name, :last_name
belongs_to :department
has_many :project_assignments
.
class ProjectAssignment < ActiveRecord::Base
attr_accessible :user_id, :project_id, :active, :notes
belongs_to :user, counter_cache: :projects_count
belongs_to :project
end
.
class Project < ActiveRecord::Base
attr_accessible :program_id, :title, :status, :topic_number, :award_number, :task_data_attributes, :user_ids, :technical_poc_id, :contacts_attributes, :project_fields_attributes, :division_id, :company_name
attr_accessor :old_project_id
belongs_to :program
belongs_to :division
belongs_to :company
has_many :users, through: :project_assignments
.
<div class="col-md-12">
<p>New Assignment</p>
<%= form_for #project.project_assignments.new, url: program_project_assignments_path(#program, #project), html: { id: 'staff-form' } do |f| %>
<%= f.select :user_id, options_from_collection_for_select(User.all, :id, :full_name), {}, class: 'form-control input-sm', placeholder: 'User' %>
<%= hidden_field_tag "project_id",nil,:value => #project.id %>
<%= f.submit 'Assign', class: 'btn-gray' %>
<% end %>
</div>
All the above code is just excerpts from their respective files. The above html works for populating the drop-down with names, but obviously no code there is attempting to add the number of assigned projects
Use options_for_select
<%= f.select :user_id, options_for_select(User.all.collect{|u|["#{u.full_name} #{u.project_assignments.count}", u.id]}), {}, class: 'form-control input-sm', placeholder: 'User' %>
It will be efficient to load the users and eager load project assignment in your controller
#users = User.includes(:project_assignment).all
I have User, which can be one of three types: Admin, Student, Teacher. Everyone has other attributes. I am trying polymorphic association one-to-one like this:
User
class User < ActiveRecord::Base
belongs_to :identity, :polymorphic => true
accepts_nested_attributes_for :identity, :allow_destroy => true
attr_accessible :email, :login, :remember_token,
:password_confirmation, :password, :role
end
Student
class Student < ActiveRecord::Base
attr_accessible :field
has_one :user, :as => :identity
end
Controller
def new
#user = User.new
end
def create
#user = User.new(params[:user]) # It fails here.
#user.identita.build
...
end
View
<%= form_for(#user) do |f| %>
<%= f.label :login %><br />
<%= f.text_field :login %>
<%= f.fields_for [:identity, Student.new] do |i| %>
<%= i.label :field %><br />
<%= i.textfield_select :field %>
<% end %>
<% end %>
When I submit this view (more complex, but this is the core), it sends hash like this:
{"utf8"=>"✓",
"authenticity_token"=>"...",
"user"=>{"login"=>"...",
"student"=> {"field"=>"..."}
}
So it fails on marked line in controller with:
ActiveModel::MassAssignmentSecurity::Error in UsersController#create
Can't mass-assign protected attributes: student
What am I doing wrong? Something like :as=>"student" or twisting the realationship?
Firstly, fix:
<%= f.fields_for [:identity, Student.new] do |i| %>
to:
<%= f.fields_for :identity, Student.new do |i| %>
Secondly, you are trying to use accepts_nested_attributes_for on a belongs_to relationship. This is not supported behavior AFAIK. Perhaps try moving that to the Student model:
class Student < ActiveRecord::Base
attr_accessible :field
has_one :user, :as => :identity
accepts_nested_attributes_for :user, :allow_destroy => true
end
and make the view like this:
<%= form_for(Student.new) do |i| %>
<%= i.fields_for :user, #user do |f| %>
<%= f.label :login %><br />
<%= f.text_field :login %>
<% end %>
<%= i.label :field %><br />
<%= i.textfield_select :field %>
<% end %>
From documentation of attr_accessible
attr_accessible will only set attributes in this list, to assign to
the rest of attributes you can use direct writer methods.
So once you've used attr_accessible, another attributes automatically will become a protected ones.