ActiveRecord Error - ruby-on-rails

I have two model class,
class Designation < ActiveRecord::Base
attr_accessible :name
validates :name, presence: true, uniqueness: { case_sensitive: false }
has_many :employee_details
accepts_nested_attributes_for :employee_details
end
and
class EmployeeDetail < ActiveRecord::Base
belongs_to :Designation
attr_accessible :bloodGroup, :dob, :doc, :doj, :empId, :name, :panNo, :status, :Designation
end
I have generated default scaffold for EmployeeDetail. from EmployeeDetail page when i tried to create and enter integer value in designation textbox, it gives me error
ActiveRecord::AssociationTypeMismatch in EmployeeDetailsController#create
Designation(#81846160) expected, got String(#75419260).
can anyone help me to sortout this problem?
EmployeeDetailController#create:-
def create
#employee_detail = EmployeeDetail.new(params[:employee_detail])
respond_to do |format|
if #employee_detail.save
format.html { redirect_to #employee_detail, notice: 'Employee detail was successfully created.' }
format.json { render json: #employee_detail, status: :created, location: #employee_detail }
else
format.html { render action: "new" }
format.json { render json: #employee_detail.errors, status: :unprocessable_entity }
end
end
end

When you associate any model, you should use the lowercase version of the model name.
Change:
belongs_to :Designation
to:
belongs_to :designation

Related

undefined method `save' for nil:NilClass for my app

[enter image description here][1]
I keep getting this error message and can not figure out why it is. I believe it is because #resturant is nil. But I do not understand why it is nil.
Is there anyway to 'print or console log' the response so I can see what the problem is
[1]: https://i.stack.imgur.com/sHUrz.png
Here is the model
class Resturant < ApplicationRecord
mount_uploader :image, ImageUploader
serialize :image, JSON # If you use SQLite, add this line
belongs_to :user, optional: true
validates :name, :description, :location, :resturant, :glutenfree, :vegan, presence: true
validates :description, length: {maximum: 1000, too_long: "%{count} characters is the maximum allowed"}
validates :title, length: {maximum: 140, too_long: "%{count} characters is the maximum allowed"}
end
here is the controller:
class Resturant < ApplicationRecord
mount_uploader :image, ImageUploader
serialize :image, JSON # If you use SQLite, add this line
belongs_to :user, optional: true
validates :name, :description, :location, :resturant, :glutenfree, :vegan, presence: true
validates :description, length: {maximum: 1000, too_long: "%{count} characters is the maximum allowed"}
validates :title, length: {maximum: 140, too_long: "%{count} characters is the maximum allowed"}
end
# GET /resturants/new
def new
#resturant = Resturant.new
end
# GET /resturants/1/edit
def edit
end
# POST /resturants or /resturants.json
def create
#resturants = Resturant.new(resturant_params)
respond_to do |format|
if #resturant.save
format.html { redirect_to resturant_url(#resturant), notice: "Resturant was successfully created." }
format.json { render :show, status: :created, location: #resturant }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #resturant.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /resturants/1 or /resturants/1.json
def update
respond_to do |format|
if #resturant.update(resturant_params)
format.html { redirect_to resturant_url(#resturant), notice: "Resturant was successfully updated." }
format.json { render :show, status: :ok, location: #resturant }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #resturant.errors, status: :unprocessable_entity }
end
end
end
# DELETE /resturants/1 or /resturants/1.json
def destroy
#resturant.destroy
respond_to do |format|
format.html { redirect_to resturants_url, notice: "Resturant was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_resturant
#resturant = Resturant.find(params[:id])
end
# Only allow a list of trusted parameters through.
def resturant_params
params.require(:resturant).permit(:name, :genre, :description, :location, :glutenfree, :vegan, :image, :resturant)
end
end
You have a typo. (It often takes a second set of fresh eyes to see these.)
You have accidentally pluralized resturant in your create action but then are using the singular later on.
You have:
#resturants = Resturant.new(resturant_params)
Change it to:
#resturant = Resturant.new(resturant_params)
(You are also misspelling "Restaurant" throughout your entire application. It is up to you if you'd like to fix that or not. I know I myself have trouble spelling that one for some silly reason.)

Multiple Select many to many Ruby on Rails not creating associative records

Well, I have a many to many association between Contacts and Lawsuits on a table named Actives. In this case, I'm trying to add many contacts to a lawsuit. The problem is: the actives not saving in lawsuits if select is multiple, only if multiple: false.
Here's the models:
#contact.rb
class Contact < ActiveRecord::Base
...
has_many :actives
has_many :lawsuits, through: :actives
#lawsuit.rb
class Lawsuit < ActiveRecord::Base
...
has_many :actives
has_many :contacts, through: :actives
accepts_nested_attributes_for :actives, allow_destroy: true
#active.rb
class Active < ActiveRecord::Base
...
belongs_to :lawsuit
belongs_to :contact
And Here's the migration table:
class CreateActives < ActiveRecord::Migration
def change
create_table :actives do |t|
t.belongs_to :contact, index: true
t.belongs_to :lawsuit, index: true
t.datetime :appointment_date
t.timestamps
end
end
end
The controller:
#controller/lawsuit.rb
#create method
def create
#lawsuit = Lawsuit.new(lawsuit_params)
respond_to do |format|
if #lawsuit.save
format.html { redirect_to #lawsuit, notice: 'Lawsuit was successfully created.' }
format.json { render :show, status: :created, location: #lawsuit }
else
format.html { render :new }
format.json { render json: #lawsuit.errors, status: :unprocessable_entity }
end
end
end
#require params
params.require(:contact).permit(:name, :lastname, :cpf, :rg, :birthdate, :profession_id, :marital_status_id, :address,
:zipcode, :city, :state, :district, :number, :actives)
The view and output params:
#/views/lawsuits/_form.html.erb
<%= form_for #lawsuit, html: {class: "ui form"} do |f| %>
...
<%= f.fields_for :actives do |w| %>
<%= w.select(:contact_id, Contact.all.pluck(:name,:id), {}, {class:"selectize-generic", multiple: true}) %>
<% end %>
<%= f.submit %>
#Params:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"9dpRjs0e2iQXgYzNqObSyzuvEnVdQYVHos922hbu0UptxiVeZfJgxgbfgFGKOUR16119VFLOfheNGogAOwez/w==",
"lawsuit"=>{"autos"=>"", "forum_id"=>"1", "lawyer_id"=>"4", "conciliation_date"=>"", "instruction_date"=>"", "fees"=>"",
"actives_attributes"=>{"0"=>{"contact_id"=>["", "2", "7", "9"]}}}, "commit"=>"Create Lawsuit"}
In last saved Lawsuit:
rails c
x = Lawsuit.last
=> #<Lawsuit id: 17, forum_id: 1, lawyer_id: 4, fees: nil, autos: "", conciliation_date: "", instruction_date: "", created_at: "2019-08-14 15:43:18", updated_at: "2019-08-14 15:43:18">
x.actives
=> #<ActiveRecord::Associations::CollectionProxy [#<Active id: 9, contact_id: nil, lawsuit_id: 17, appointment_date: nil, created_at: "2019-08-14 15:43:18", updated_at: "2019-08-14 15:43:18">]>
I've been wasting a lot of time on this, I've already try everything, recreate models, tried simple_form gem, change in params, etc. I'm lost.
Anyone can help?
GitHub for the project:
https://github.com/killerowns/lawsuit-manager-rails
It seems to me that Active is a icky name for your model. Why not call it LawsuitContact? And then do:
# == Schema Information
#
# Table name: lawsuit_contacts
#
# id :integer not null, primary key
# lawsuit_id :integer
# contact_id :integer
# appointment_date :datetime
# created_at :datetime not null
# updated_at :datetime not null
#
class LawsuitContact < ActiveRecord::Base
belongs_to :lawsuit
belongs_to :contact
end
Then:
class Contact < ActiveRecord::Base
has_many :lawsuit_contacts
has_many :lawsuits, through: :lawsuit_contacts
end
And:
class Lawsuit < ActiveRecord::Base
has_many :lawsuit_contacts
has_many :contacts, through: :lawsuit_contacts
end
Given that your params look something like:
{
"lawsuit"=>{
"autos"=>"",
"forum_id"=>"1",
"lawyer_id"=>"4",
"conciliation_date"=>"",
"instruction_date"=>"",
"fees"=>"",
"actives_attributes"=>{
"0"=>{
"contact_id"=>["", "2", "7", "9"]
}
}
},
"commit"=>"Create Lawsuit"
}
...in your controller you could do something like:
def create
#lawsuit = Lawsuit.new(lawsuit_params)
respond_to do |format|
if #lawsuit.save
#lawsuit.contacts << Contact.where(id: contact_ids)
format.html { redirect_to #lawsuit, notice: 'Lawsuit was successfully created.' }
format.json { render :show, status: :created, location: #lawsuit }
else
format.html { render :new }
format.json { render json: #lawsuit.errors, status: :unprocessable_entity }
end
end
end
def update
#lawsuit = Lawsuit.find_by(id: params[:id])
respond_to do |format|
if #lawsuit.update(lawsuit_params)
# Assuming the user can remove a contact from a lawsuit, you'll want to
# 'unlink' the lawsuit and the contact by destroying all the relevant
# LawsuitContact join models:
#lawsuit.lawsuit_contacts.where.not(contact_id: contact_ids).destroy_all
# Then, you'll want to add any new contacts that the user might have
# added:
#lawsuit.contacts << Contact.where(id: contact_ids)
format.html { redirect_to #lawsuit, notice: 'Lawsuit was successfully updated.' }
format.json { render :show, status: :created, location: #lawsuit }
else
format.html { render :edit }
format.json { render json: #lawsuit.errors, status: :unprocessable_entity }
end
end
end
private
def lawsuit_params
params.require(:lawsuit).permit(
:autos,
:forum_id,
:lawyer_id,
:conciliation_date,
:instruction_date,
:fees
)
end
def contact_ids
params[:lawsuit][:actives_attributes].try(:[], '0').try(:[], :contact_id)
end

Rails 4- Complex model validation (has_many, through)

I am trying to validate the "name" attribute in my Ingredient model. However, when I add validates :name, :uniqueness => true in my Ingredient model, it does not validate the name (can insert ingredient with same name). The ingredient model has a complex relationship with other model. Please see the code below.
My ultimate goal is to allows user to create ingredient if the ingredient does not exist in the Ingredient table. If the ingredient already existed, used the ingredient id for quantity. If anyone has any idea how to achieve that, please provide the solution to it. Thanks in advance.
ingredient.rb
class Ingredient < ActiveRecord::Base
has_many :quantities
has_many :recipes, through: :quantities
validates :name, :presence => true, :uniqueness => true
end
quantity.rb
class Quantity < ActiveRecord::Base
belongs_to :ingredient
belongs_to :recipe
accepts_nested_attributes_for :ingredient,
:reject_if => :all_blank
validates :ingredient, :uniqueness => true
end
recipe.rb
class Recipe < ActiveRecord::Base
has_many :quantities,
dependent: :destroy
has_many :ingredients,
:through => :quantities
accepts_nested_attributes_for :quantities,
reject_if: :all_blank,
allow_destroy: true
accepts_nested_attributes_for :ingredients
end
view section for creating Ingredient:
%strong Ingredients:
%fieldset#recipe-ingredients
%br
= f.fields_for :quantities do |builder|
= render 'recipe/quantity_fields', f: builder
.links
= link_to_add_association 'add ingredient', f, :quantities, 'data-association-insertion-node' => '#recipe-ingredients', 'data-assoication-insertion-moethod' => "append", :wrap_object => Proc.new{|quantity| quantity.ingredient.build ; quantity}
%br
Ingredient controller:
class IngredientController < ApplicationController
before_action :set_ingredient, only: [:show, :edit, :update, :destroy]
# GET /ingredients
# GET /ingredients.json
def index
#ingredients = Ingredient.all
end
# GET /ingredients/1
# GET /ingredients/1.json
def show
end
# GET /ingredients/new
def new
#ingredient = Ingredient.new
end
# GET /ingredients/1/edit
def edit
end
def create
#ingredient = Ingredient.new(ingredient_params)
respond_to do |format|
if #ingredient.save
format.html { redirect_to #ingredient, notice: 'Ingredient was successfully created.' }
format.json { render :show, status: :created, location: #ingredient }
else
format.html { render :new }
format.json { render json: #ingredient.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /ingredients/1
# PATCH/PUT /ingredients/1.json
def update
respond_to do |format|
if #ingredient.update(ingredient_params)
format.html { redirect_to #ingredient, notice: 'Ingredient was successfully updated.' }
format.json { render :show, status: :ok, location: #ingredient }
else
format.html { render :edit }
format.json { render json: #ingredient.errors, status: :unprocessable_entity }
end
end
end
# DELETE /ingredients/1
# DELETE /ingredients/1.json
def destroy
#ingredient.destroy
respond_to do |format|
format.html { redirect_to ingredients_url, notice: 'Ingredient was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_ingredient
#ingredient = Ingredient.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def ingredient_params
params.require(:ingredient).permit(:name)
end
end
It seems like a known issue probably a bug. Check this: https://github.com/rails/rails/issues/20676

How to perform validation on associated attributes

I tried to validate associated attribute access_module_id in role
model but it doesn't work. How to give validation of presence: true to other model's attribute in role form? Here is associations
role.rb
class Role < ActiveRecord::Base
....
has_many :access_module_roles, :dependent => :destroy
has_many :access_modules, through: :access_module_roles
validates :name,:access_module_id, presence: true # I want to validate presence of access_module_ids in role form
end
access_module.rb
class AccessModule < ActiveRecord::Base
has_many :access_module_roles
has_many :roles, through: :access_module_roles
end
access_module_roles.rb
class AccessModuleRole < ActiveRecord::Base
belongs_to :access_module
belongs_to :role
end
Update
I have tried below validation and if I select one, two or all still getting an error like
"Access module ids can't be blank"
validates_presence_of :access_module_ids
Controller
def create
#role = Role.new(role_params)
respond_to do |format|
if #role.save
params[:role][:access_module_ids].each do |acmi|
AccessModuleRole.create!(:role_id => #role.id, :access_module_id => acmi) if acmi!=""
end
format.html { redirect_to roles_path, notice: 'Role was successfully created.' }
format.json { render :index, status: :created, location: #role }
else
format.html { render :new }
format.json { render json: #role.errors, status: :unprocessable_entity }
end
end
end
I found that I am doing mistake in Create method. I was inserting data to AccessModuleRole after doing save so it gets validation error while creating..And was getting parameter as nil
Corrected code:
def create
#role = Role.new(role_params)
#role.access_module_ids = params[:role][:access_module_ids]
respond_to do |format|
if #role.save
format.html { redirect_to roles_path, notice: 'Role was successfully created.' }
format.json { render :index, status: :created, location: #role }
else
format.html { render :new }
format.json { render json: #role.errors, status: :unprocessable_entity }
end
end
end
Permitted Role's attributes:
private
def role_params
params.require(:role).permit(:name,:chk_ids ,:description, :code, :is_active, :access_module_ids)
end
Now it works perfectly.. Thanks to RAJ to pointing me :)

undefined method `title' for nil:NilClass in mailer

I am pretty new to ror, and I run into some issue with my application:
I have a ticket model and a comment model,
class Ticket < ActiveRecord::Base
attr_accessible :content, :title, :user, :priority, :category, :status
validates_presence_of :content, :title, :category
has_many :comments, dependent: :destroy
accepts_nested_attributes_for :comments
end
class Comment < ActiveRecord::Base
attr_accessible :content, :ticket_id, :user
belongs_to :ticket
end
Now I want to send a mail when a comment is created:
In comment controller:
def create
#comment = Comment.new(params[:comment])
respond_to do |format|
if #comment.save
TicketMailer.ticket_commented(#comment).deliver
format.html { redirect_to #comment, notice: 'Comment was successfull created.' }
format.json { render json: #comment, status: :created, location: #comment }
else
format.html { render action: "new" }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
Then in mailer:
class TicketMailer < ActionMailer::Base
default from: "helpdesk#testing.com"
def ticket_commented(comment)
#comment = comment
#ticket = Ticket.find_by_id(#comment.id)
mail(:to => #comment.user, :subject => 'New comment')
end
end
But when I try to call
<%= #ticket.title %>
In view, I got this error: undefined methodtitle' for nil:NilClass`
Did I do something wrong? Or how can I pass #ticket into the mailer correctly?
In your mailer you're trying to find a ticket by providing the id of a comment, change the line #ticket = Ticket.find_by_id(#comment.id) to #ticket = #comment.ticket

Resources