I am working on a Rails project and I am using namespacing for the models and controllers. That is the child models (admin and student) are put in a directory called user and the controllers are put in a directory called users.
I also have admins_controller and students_controller that use the admin model and the student model respectively. These controllers are namespaced using users directory.
I then have a personal_info model that contains more details about the user, such as gender, age, date of birth. The personal_info table has a one-to-one relationship with the user model.
Here's my code;
Personal Info model:
class PersonalInfo < ApplicationRecord
belongs_to :user
end
User model:
class User < ApplicationRecord
has_secure_password
has_one :personal_info, class_name: 'PersonalInfo', dependent: :destroy
accepts_nested_attributes_for :personal_info, allow_destroy: true
end
Admin model:
class User::Admin < User
end
Admin Controller:
class Users::AdminsController < ApplicationController
before_action :set_admin, only: [:show, :edit, :update, :destroy]
# GET /admins
# GET /admins.json
def index
#admins = User::Admin.all
end
# GET /admins/1
# GET /admins/1.json
def show
end
# GET /admins/new
def new
#admin = User::Admin.new
#admin.build_personal_info
end
# GET /admins/1/edit
def edit
end
# POST /admins
# POST /admins.json
def create
#admin = User::Admin.new(admin_params)
#admin.build_personal_info
respond_to do |format|
if #admin.save
format.html { redirect_to users_admin_path(#admin), notice: 'Admin was successfully created.' }
format.json { render :show, status: :created, location: users_admin_path(#admin) }
else
format.html { render :new }
format.json { render json: #admin.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /admins/1
# PATCH/PUT /admins/1.json
def update
respond_to do |format|
if #admin.update(admin_params)
format.html { redirect_to users_admin_path(#admin), notice: 'Admin was successfully updated.' }
format.json { render :show, status: :ok, location: users_admin_path(#admin) }
else
format.html { render :edit }
format.json { render json: #admin.errors, status: :unprocessable_entity }
end
end
end
# DELETE /admins/1
# DELETE /admins/1.json
def destroy
#admin.destroy
respond_to do |format|
format.html { redirect_to users_admins_url, notice: 'Admin was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_admin
#admin = User::Admin.find(params[:id])
end
# Only allow a list of trusted parameters through.
def admin_params
params.require(:user_admin).permit(
:email, :password, :role_id,
personal_info_attributes: [ :id, :first_name, :last_name, :phone,
:gender, :dob, :address, :city, :state,
:country ]
)
end
end
Routes:
Rails.application.routes.draw do
namespace :users do
resources :admins
resources :students
end
end
_form.html.erb:
<% if #admin.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#admin.errors.count, "error") %> prohibited this admin from being saved:</h2>
<ul>
<% #admin.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= fields_for :personal_info do |form| %>
<div class="field">
<%= form.label :first_name %>
<%= form.text_field :first_name %>
</div>
<div class="field">
<%= form.label :last_name %>
<%= form.text_field :last_name %>
</div>
<% end %>
<div class="field">
<%= form.label :email %>
<%= form.text_field :email %>
</div>
<%= fields_for :personal_info do |form| %>
<div class="field">
<%= form.label :phone %>
<%= form.text_field :phone %>
</div>
<% end %>
<div class="field">
<%= form.label :password %>
<%= form.text_field :password %>
</div>
<div class="actions">
<%= form.submit %>
</div>
new.html.erb:
<h1>Editing Admin</h1>
<%= form_with(model: #admin, url: users_admins_path, local: true) do |form| %>
<%= render partial: 'form', admin: #admin, locals: { form: form } %>
<% end %>
<%= link_to 'Back', users_admins_path %>
However, when I try to create a new admin or update an already existing admin after adding inputs to the displayed form no Personal Info data is saved on the database. They are all nil.
PersonalInfo Load (0.3ms) SELECT "personal_infos".* FROM "personal_infos" WHERE "personal_infos"."user_id" = $1 LIMIT $2 [["user_id", 6], ["LIMIT", 1]]
=> #<PersonalInfo id: 2, first_name: nil, last_name: nil, phone: nil, gender: nil, dob: nil, address: nil, city: nil, state: nil, country: nil, user_id: 6, created_at: "2020-06-26 13:37:16", updated_at: "2020-06-26 13:37:16">
I have tried to get this resolved, but no luck yet. Any form of help will be highly appreciated.
you should call your fields_for from admin form as:
<%= form.fields_for :personal_info do |form| %>
otherwise it sends these params independent from admin, rather than nested as you'd like.
fwiw, for better reading, I would consider rename your inner personal_info form variable to not clash with admin form variable. But that's just a suggestion. :)
Related
I'm trying to create a nested form in Ruby on Rails. The form appears as expected. But when it is saved the nested attribute, Booking, is not saved.
cleaner.rb
class Cleaner < ActiveRecord::Base
validates_presence_of :first_name
validates_presence_of :last_name
validates_presence_of :quality_score
validates :quality_score, inclusion: 0.0...5.0
has_many :assignments
has_many :bookings
has_many :cities, through: :assignments
has_many :customers, through: :bookings
end
customer.rb
class Customer < ActiveRecord::Base
validates_presence_of :first_name
validates_presence_of :last_name
validates_uniqueness_of :phone_number
belongs_to :city
has_many :bookings
has_many :cleaners, through: :bookings
accepts_nested_attributes_for :bookings
end
booking.rb
class Booking < ActiveRecord::Base
belongs_to :customer
belongs_to :cleaner
validates_presence_of :customer
validates_presence_of :cleaner
validates_presence_of :date
end
customers_controller.rb
class CustomersController < ApplicationController
before_action :set_customer, only: %i[show edit update destroy]
def index
#customers = Customer.all
end
def show; end
def new
#customer = Customer.new
end
def edit; end
def create
#customer = Customer.find_or_initialize_by(phone_number: params[:phone_number])
#customer.assign_attributes(customer_params)
respond_to do |format|
if #customer.save
format.html { redirect_to #customer, notice: 'Customer was successfully created.' }
format.json { render :show, status: :created, location: #customer }
else
format.html { render :new }
format.json { render json: #customer.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #customer.update(customer_params)
format.html { redirect_to #customer, notice: 'Customer was successfully updated.' }
format.json { render :show, status: :ok, location: #customer }
else
format.html { render :edit }
format.json { render json: #customer.errors, status: :unprocessable_entity }
end
end
end
def destroy
#customer.destroy
respond_to do |format|
format.html { redirect_to customers_url, notice: 'Customer was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_customer
#customer = Customer.find(params[:id])
end
def customer_params
params.require(:customer).permit(:first_name, :last_name, :phone_number, :city, :city_id, bookings_attributes: %i[cleaner_id date])
end
end
HomeController.rb
class HomeController < ApplicationController
def index
#customer = Customer.new
#customer.bookings.build
end
end
Parameters
{"utf8"=>"✓", "authenticity_token"=>"c4xo2M4r57+/xBsmcc+7yajpQU13u1kiwmOthx/nP7HiJXJIfS9/OqC0MrWCcaDrSW/xN8UGk2+LVfnUnbTb3A==", "customer"=>{"first_name"=>"adfad", "last_name"=>"fad", "phone_number"=>"9392323", "city_id"=>"1", "bookings_attributes"=>{"0"=>{"cleaner_id"=>"1"}}}, "#<ActionView::Helpers::FormBuilder:0x007f86bec96480>"=>{"date(1i)"=>"2017", "date(2i)"=>"8", "date(3i)"=>"2"}, "commit"=>"Create Customer"}
updated form
<h1>Sign Up Now</h1>
<%= form_for #customer do |f| %>
<% if #customer.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#customer.errors.count, "error") %> prohibited this customer from being saved:</h2>
<ul>
<% #customer.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :first_name %><br>
<%= f.text_field :first_name %>
</div>
<div class="field">
<%= f.label :last_name %><br>
<%= f.text_field :last_name %>
</div>
<div class="field">
<%= f.label :phone_number %><br>
<%= f.text_field :phone_number %>
</div>
<div class="field">
<%= f.label :city %><br>
<%= f.select :city_id, options_for_select(City.pluck(:name, :id)) %>
</div>
<%= f.fields_for :bookings do |b| %>
<%= b.date_select :date %>
<br>
<%= b.select :cleaner_id, Cleaner.all.pluck(:first_name, :id) %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
It's now failing with 2 errors
Bookings customer can't be blank
Bookings date can't be blank
use the iteration of the first #customer so rails can read properly
i saw this example https://www.sitepoint.com/complex-rails-forms-with-nested-attributes/
<%= f.fields_for :booking do |ff| %>
<%= ff.select :city_id,options_for_select(City.pluck(:name, :id)) %>
i hope it works cross finger :)
It creates the object, says that it was successfully created, but all fields are saved in the database with nil values. Only created_at and updated_at are saved normally.
Some methods of my controllers/admin/categories_controller.rb
def new
#admin_category = Category.new
end
# GET /admin/categories/1/edit
def edit
end
# POST /admin/categories
# POST /admin/categories.json
def create
#admin_category = Category.new(params[:category])
respond_to do |format|
if #admin_category.save
format.html { redirect_to admin_category_path(#admin_category), notice: 'Category was successfully created.' }
format.json { render :show, status: :created, location: admin_category_path(#admin_category) }
else
format.html { render :new }
format.json { render json: #admin_category.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /admin/categories/1
# PATCH/PUT /admin/categories/1.json
def update
respond_to do |format|
if #admin_category.update(admin_category_params)
format.html { redirect_to #admin_category, notice: 'Category was successfully updated.' }
format.json { render :show, status: :ok, location: #admin_category }
else
format.html { render :edit }
format.json { render json: #admin_category.errors, status: :unprocessable_entity }
end
end
end
This is my models/category model:
class Category < ActiveRecord::Base
belongs_to :category
end
This is my routes.br file
namespace :admin do
resources :categories
end
My views/admin/categories/_form.html.erb
<%= form_for(#admin_category, url: admin_categories_path) do |f| %>
<% if #admin_category.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#admin_category.errors.count, "error") %> prohibited this admin_category from being saved:</h2>
<ul>
<% #admin_category.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :is_active %><br>
<%= f.check_box :is_active %>
</div>
<div class="field">
<%= f.label :main_menu %><br>
<%= f.check_box :main_menu %>
</div>
<div class="field">
<%= f.label :category_id %><br>
<%= f.number_field :category_id %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
And when I try to edit, I get this error:
No route matches [PATCH] "/admin/categories"
I'm very newbie to Ruby on Rails, so I would apreciate any help!
Thanks!
You are only passing :category when creating a new Category:
def create
#admin_category = Category.new(params[:category])
Change it to Category.new(user_params) and try again. This will pass on all parameters you're creating and feed it to the database.
Also, permit the parameters you are trying to pass:
def user_params
params.require(:admin_category).permit(:name, :is_active, :main_menu, :category_id)
end
Strong Params:
#app/controllers/categories_controller.rb
class CategoriesController < ApplicationController
def create
#admin_category = Category.new category_params
end
private
def category_params
params.require(:category).permit(:name, :is_active, :main_menu, :category_id)
end
end
--
As a tip, if you're using nested objects with forms, you can pass both objects in an array to create the nested path:
#app/views/admin/categories/new.html.erb
<%= form_for [:admin, #admin_category] do |f| %>
I have two models :
Post and Picture
class Post < ActiveRecord::Base
has_many :picture, :dependent => :destroy
accepts_nested_attributes_for :picture, :allow_destroy => true, :reject_if => lambda { |t| t['pictures'].nil? }
end
and
class Picture < ActiveRecord::Base
belongs_to :posts
has_attached_file :image, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/:style/missing.png"
validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
end
Picture has a paperclip attachment : image
I created a nested form but i'm not able to know if my picture is saved correctly since i can't display in the show page.
Here is my form :
<%= form_for #post, html: { multipart: true} do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #post.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_area :description %>
</div>
<div class="field">
<%= f.label :brand %><br>
<%= f.text_field :brand %>
</div>
<div class="field">
<%= f.label :model %><br>
<%= f.text_field :model %>
</div>
<div class="field"><%= f.fields_for :picture do |p| %>
<%= p.file_field :image %>
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
My show page :
<p id="notice"><%= notice %></p>
<%= #post.picture.each do |pic| %>
<%= image_tag pic.image.url(:medium) %>
<% end %>
<p>
<strong>Title:</strong>
<%= #post.title %>
</p>
<p>
<strong>Description:</strong>
<%= #post.description %>
</p>
<p>
<strong>Brand:</strong>
<%= #post.brand %>
</p>
<p>
<strong>Model:</strong>
<%= #post.model %>
</p>
<%= link_to 'Edit', edit_post_path(#post) %> |
<%= link_to 'Back', posts_path %>
The post controller :
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
# GET /posts
# GET /posts.json
def index
#posts = Post.all
end
# GET /posts/1
# GET /posts/1.json
def show
end
# GET /posts/new
def new
#post = Post.new
#post.picture.build
end
# GET /posts/1/edit
def edit
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(post_params)
respond_to do |format|
if #post.save
if params[:image]
params[:image].each { |image|
#post.picture.create(image: image)
}
end
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: #post }
else
format.html { render :edit }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:title, :description, :brand, :model, picture_attributes: [ :id, :post_id, :image, :_destroy])
end
end
When i heat create post, i have no error the post is rendered but instead of having the image displayed i have this : "[]" ?
Terminal output :
Processing by PostsController#show as HTML
Parameters: {"id"=>"8"}
Post Load (0.4ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT 1 [["id", 8]]
Picture Load (0.3ms) SELECT "pictures".* FROM "pictures" WHERE "pictures"."post_id" = ? [["post_id", 8]]
Is there something i did wrong ?
The first issue you have is that you've referenced your associations incorrectly:
#app/models/post.rb
class Post < ActiveRecord::Base
has_many :pictures #-> plural
end
#app/models/picture.rb
class Picture < ActiveRecord::Base
belongs_to :post #-> singular
has_attached_file :image
validates :image, content_type: { content_type: /\Aimage\/.*\Z/ }
end
You can see about the association names here:
A pro tip is to use the paperclip_defaults options in your application.rb:
#config/application.rb
...
config.paperclip_defaults: {
styles: { medium: "300x300>", thumb: "100x100>" },
default_url: "/images/:style/missing.png"
}
This will allow you to set the "defaults" for all implementations of Paperclip in your app, which can be overridden as you need in each model. Just makes it less messy I find...
In regards your error, you have all the pieces in place; I think the issue is your association names (see above).
This is what I would have:
#app/controllers/posts_controller.rb
class PostsController < ApplicationController
def new
#post = Post.new
#post.pictures.build #-> plural
end
def create
#post = Post.new post_params
#post.save
end
private
def post_params
params.require(:post).permit(:title, :description, :brand, :model, picture_attributes: [:image, :_destroy])
end
end
You'd then be able to use the following form:
#app/views/posts/new.html.erb
<%= form_for #post, multipart: true do |f| %>
<%= f.fields_for :pictures do |p| %>
<%= p.file_field :image %>
<% end %>
<%= f.submit %>
<% end %>
--
This should submit to your db properly; to display the images, you can use the following:
#app/views/posts/show.html.erb
<% #post.pictures.each do |picture| %>
<%= image_tag picture.image.url %>
<% end %>
Updated version - I have taken the initial advice provided (thanks for that!) but I'm still having the same issue. I have updated everything below.
I have two models, products that belong to a store.
I'm attempting to display a related object's column (Store.name) in a couple of views for products that belong to a store and can't seem to get the store to save correctly. Please note: Still very new to this and learning.
Model for Product:
class Product < ActiveRecord::Base
belongs_to :store
validates_presence_of :name, :url, :price
end
Model for Store:
class Store < ActiveRecord::Base
has_many :products
has_many :pins, through: :products
accepts_nested_attributes_for :products
end
Controller for Product:
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
# GET /products
# GET /products.json
def index
#products = Product.all
end
# GET /products/1
# GET /products/1.json
def show
end
# GET /products/new
def new
#product = Product.new
#stores = Store.all
end
# GET /products/1/edit
def edit
end
# POST /products
# POST /products.json
def create
#product = Product.new(product_params)
respond_to do |format|
if #product.save
format.html { redirect_to #product, notice: 'Product was successfully created.' }
format.json { render action: 'show', status: :created, location: #product }
else
format.html { render action: 'new' }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /products/1
# PATCH/PUT /products/1.json
def update
respond_to do |format|
if #product.update(product_params)
format.html { redirect_to #product, notice: 'Product was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# DELETE /products/1
# DELETE /products/1.json
def destroy
#product.destroy
respond_to do |format|
format.html { redirect_to products_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_product
#product = Product.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def product_params
params.require(:product).permit(:name, :description, :imageurl, :url, :price, :Store_id)
end
end
Form for products
<%= form_for(#product) do |f| %>
<% if #product.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#product.errors.count, "error") %> prohibited this product from being saved:</h2>
<ul>
<% #product.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group">
<%= f.label :name, "Name" %>
<%= f.text_field :name, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :description, "Description" %>
<%= f.text_area :description, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :imageurl, "Image" %>
<%= f.text_field :imageurl, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :url, "Web Address" %>
<%= f.text_field :url, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :price, "Price" %>
$<%= f.text_field :price, class: "form-control" %>
</div>
<div class="form-group">
<%= collection_select(:product, :Store_id, Store.all, :id, :name, {:prompt=> "Select A Store"}, {:class => "form-control"} ) %>
</div>
<div class="form-group">
<%= f.submit class: "btn btn-primary" %>
</div>
<% end %>
<%= params.inspect %>
View for products (show.html.erb):
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= #product.name %>
</p>
<p>
<strong>Description:</strong>
<%= #product.description %>
</p>
<p>
<strong>Store Id:</strong>
<%= #product.Store_id %>
</p>
<p>
<strong>Store Name:</strong>
<%= #product.store.try(:name) %>
</p>
<p>
<strong>Image:</strong>
<%= #product.imageurl %>
</p>
<p>
<strong>Url:</strong>
<%= #product.url %>
</p>
<p>
<strong>Price:</strong>
$<%= #product.price %>
</p>
<%= params.inspect %>
<%= link_to 'Edit', edit_product_path(#product) %> |
<%= link_to 'Back', products_path %>
You'll notice that I have .try in place where I'm referencing product.store.name from product.store so that I stop getting the error listed in the subject of this post.
When I look up the product I'm viewing using the console I see that Store_id: 2
When I look up the store with id of 2 I see that Store_id: 1 - so there is a value present there.
I printed params on the show view and only get this: {"action"=>"show", "controller"=>"products", "id"=>"2"}.
Can anyone find what I'm missing in this whole set up to get product.store.name to display in my product views? Let me know if I can provide more info!
First, you should be using snake_case for attributes. UpperCamelCase is reserved for constant names in Ruby, that includes things like classes and modules. Update your code to not use UpperCamelCase style naming for attributes (eg. ProdDesc, ProdImageUrl). Also it is unnecessary to use prefixes like Prod* for attributes.
So instead of
class Product < ActiveRecord::Base
belongs_to :store
validates_presence_of :ProdTitle, :ProdUrl, :ProdPrice
end
Your class will look like this:
class Product < ActiveRecord::Base
belongs_to :store
validates_presence_of :title, :url, :price
end
You can read more about Ruby and Rails naming conventions here:
http://rubylearning.com/satishtalim/ruby_names.html
https://github.com/bbatsov/rails-style-guide
I suspect that this causes the problem. You will also need to rename columns in database and change your controller and view code to reflect the change. If you can, please start again with your application.
You have taken name for field In database which are non conventional. By default The active record looks for store_id field in product table . Field name in a table should be snake case .so now you have to explicitly tell in product model the foreign key for store model
I have a rails form to collect information on people for a family tree application. There are two drop down boxes that are used to assign the parents of the person being edited/created, however when a selection is made in either, or both, of these boxes, it is not committed to the database. It doesn't throw any exceptions, however when I check the database, the fatherID and motherID fields remain as null.
Here is the complete code for the form:
Does anybody have any ideas where I'm going astray?
Thanks.
<%= form_for(#person) do |f| %>
<% if #person.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#person.errors.count, "error") %> prohibited this person from being saved:</h2>
<ul>
<% #person.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :FirstName %><br>
<%= f.text_field :FirstName %>
</div>
<div class="field">
<%= f.label :LastName %><br>
<%= f.text_field :LastName %>
</div>
<div class="field">
<%= f.label :MaidenName %><br>
<%= f.text_field :MaidenName %>
</div>
<div class="field">
<%= f.label :Sex %><br>
<%= f.select(:Sex, options_for_select([['Male', 'M'], ['Female', 'F']]))%>
</div>
<div class="field">
<p>Parents:</p>
Mother: <%= select(:motherID, options_from_collection_for_select(Person.all, :id, :FirstName), :include_blank => true)%>
Father: <%= select(:fatherID, options_from_collection_for_select(Person.all, :id, :FirstName), :include_blank => true)%>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Controller code
class PeopleController < ApplicationController
before_action :set_person, only: [:show, :edit, :update, :destroy]
# GET /people
# GET /people.json
def index
#people = Person.all
end
# GET /people/1
# GET /people/1.json
def show
end
# GET /people/new
def new
#person = Person.new
end
# GET /people/1/edit
def edit
end
# POST /people
# POST /people.json
def create
#person = Person.new(person_params)
respond_to do |format|
if #person.save
format.html { redirect_to #person, notice: 'Person was successfully created.' }
format.json { render action: 'show', status: :created, location: #person }
else
format.html { render action: 'new' }
format.json { render json: #person.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /people/1
# PATCH/PUT /people/1.json
def update
respond_to do |format|
if #person.update(person_params)
format.html { redirect_to #person, notice: 'Person was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #person.errors, status: :unprocessable_entity }
end
end
end
# DELETE /people/1
# DELETE /people/1.json
def destroy
#person.destroy
respond_to do |format|
format.html { redirect_to people_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_person
#person = Person.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def person_params
params.require(:person).permit(:FirstName, :LastName, :MaidenName, :Sex)
end
end
Model Code
class Person < ActiveRecord::Base
has_ancestry
end
:motherID and :fatherID need to be in params.require(:person).permit(:FirstName, :LastName, :MaidenName, :Sex) otherwise the controller does not pass these values to the model for them to be saved.
For more information about strong parameters, see the rails guide: http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters