factorygirl create model association NoMethodError: undefined method - ruby-on-rails

When I try to run FactoryGirl.create(:job, :purchased) I get the following error. I have been battling this for a long time now and I believe I have a pluralization issue.
Issue
Models
class Job < ActiveRecord::Base
belongs_to :company
belongs_to :category
has_one :coupon
has_many :payments
end
class Payment < ActiveRecord::Base
belongs_to :job
belongs_to :coupon
end
class Coupon < ActiveRecord::Base
belongs_to :job
end
Factory
FactoryGirl.define do
factory :job do
category
company
title { FFaker::Company.position }
location { "#{FFaker::Address.city}, #{FFaker::AddressUS.state}" }
language_list { [FFaker::Lorem.word] }
short_description { FFaker::Lorem.sentence }
description { FFaker::HTMLIpsum.body }
application_process { "Please email #{FFaker::Internet.email} about the position." }
trait :featured do |job|
job.is_featured true
end
trait :reviewed do |job|
job.reviewed_at { Time.now }
end
trait :purchased do |job|
job.reviewed_at { Time.now }
job.start_at { Time.now }
job.end_at { AppConfig.product['settings']['job_active_for_day_num'].day.from_now }
job.paid_at { Time.now }
association :payment, factory: :payment
end
trait :expired do |job|
start_at = (200..500).to_a.sample.days.ago
job.reviewed_at { start_at }
job.start_at { start_at }
job.end_at { |j| j.start_at + AppConfig.product['settings']['job_active_for_day_num'].days }
job.paid_at { start_at }
# TBD ADD PAYMENT
end
end
end
Partial Schema
create_table "payments", force: :cascade do |t|
t.decimal "price_paid", precision: 8, scale: 2, default: 0.0
t.string "stripe_customer_token"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "jobs", force: :cascade do |t|
t.string "title", limit: 50, null: false
t.string "slug", limit: 250, null: false, index: {name: "index_jobs_on_slug"}
t.string "vanity_url", limit: 250
t.string "location", limit: 100, null: false
t.string "short_description", limit: 250, null: false
t.text "description", null: false
t.text "application_process", null: false
t.boolean "is_featured", default: false
t.datetime "start_at"
t.datetime "end_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "company_id", index: {name: "index_jobs_on_company_id"}, foreign_key: {references: "companies", name: "fk_jobs_company_id", on_update: :no_action, on_delete: :no_action}
t.datetime "deleted_at", index: {name: "index_jobs_on_deleted_at"}
t.integer "category_id", index: {name: "index_jobs_on_category_id"}, foreign_key: {references: "categories", name: "fk_jobs_category_id", on_update: :no_action, on_delete: :no_action}
t.datetime "paid_at"
t.datetime "reviewed_at"
t.integer "payment_id", index: {name: "index_jobs_on_payment_id"}, foreign_key: {references: "payments", name: "fk_jobs_payment_id", on_update: :no_action, on_delete: :no_action}
end
create_table "coupons", force: :cascade do |t|
t.integer "code", limit: 8, null: false, index: {name: "index_coupons_on_code", unique: true}
t.integer "percent_discount", limit: 2, null: false
t.datetime "start_at", null: false
t.datetime "end_at", null: false
t.datetime "executed_at"
t.datetime "deleted_at", index: {name: "index_coupons_on_deleted_at"}
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "job_id", index: {name: "index_coupons_on_job_id"}, foreign_key: {references: "jobs", name: "fk_coupons_job_id", on_update: :no_action, on_delete: :no_action}
t.integer "payment_id", index: {name: "index_coupons_on_payment_id"}, foreign_key: {references: "payments", name: "fk_coupons_payment_id", on_update: :no_action, on_delete: :no_action}
end
Updates per chat below
create_table "jobs", force: :cascade do |t|
t.string "title", limit: 50, null: false
t.string "slug", limit: 250, null: false, index: {name: "index_jobs_on_slug"}
t.string "vanity_url", limit: 250
t.string "location", limit: 100, null: false
t.string "short_description", limit: 250, null: false
t.text "description", null: false
t.text "application_process", null: false
t.boolean "is_featured", default: false
t.datetime "start_at"
t.datetime "end_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "company_id", index: {name: "index_jobs_on_company_id"}, foreign_key: {references: "companies", name: "fk_jobs_company_id", on_update: :no_action, on_delete: :no_action}
t.datetime "deleted_at", index: {name: "index_jobs_on_deleted_at"}
t.integer "category_id", index: {name: "index_jobs_on_category_id"}, foreign_key: {references: "categories", name: "fk_jobs_category_id", on_update: :no_action, on_delete: :no_action}
t.datetime "paid_at"
t.datetime "reviewed_at"
end
create_table "coupons", force: :cascade do |t|
t.integer "code", limit: 8, null: false, index: {name: "index_coupons_on_code", unique: true}
t.integer "percent_discount", limit: 2, null: false
t.datetime "start_at", null: false
t.datetime "end_at", null: false
t.datetime "executed_at"
t.datetime "deleted_at", index: {name: "index_coupons_on_deleted_at"}
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "job_id", index: {name: "index_coupons_on_job_id"}, foreign_key: {references: "jobs", name: "fk_coupons_job_id", on_update: :no_action, on_delete: :no_action}
end
create_table "payments", force: :cascade do |t|
t.decimal "price_paid", precision: 8, scale: 2, default: 0.0
t.string "stripe_customer_token"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "job_id", index: {name: "index_payments_on_job_id"}, foreign_key: {references: "jobs", name: "fk_payments_job_id", on_update: :no_action, on_delete: :no_action}
t.integer "coupon_id", index: {name: "index_payments_on_coupon_id"}, foreign_key: {references: "coupons", name: "fk_payments_coupon_id", on_update: :no_action, on_delete: :no_action}
end
Errors
TRAITS WORKING
trait :purchased do |job|
job.reviewed_at { Time.now }
job.start_at { Time.now }
job.end_at { AppConfig.product['settings']['job_active_for_day_num'].day.from_now }
job.paid_at { Time.now }
payments { |j| [j.association(:payment)] }
end

In your trait your are defining association :payment, factory: :payment
but job has_many payments.
To work, your models should be:
class Job < ActiveRecord::Base
belongs_to :payment
end
class Payment < ActiveRecord::Base
has_many :jobs
end
If you want to keep your model as you have and create a trait with a job containing multiple payments, you need to do something like this:
How to set up factory in FactoryGirl with has_many association

Related

Rails has_many_through query not returning results

I have some models with a has_many_through join. I am trying to get a list of classification_fields and their properties where the classification_id is in the array I am pasing through. This following query doesn't seem to be getting anything. What am I doing wrong?
Get the parent ids and query the classificationfields:
#parentids = #classification.self_and_ancestors_ids.to_a if params[:class_id].present?
#details = ClassificationField.includes(:classifications).where(classification_id: [#parentids] ) if params[:sub].present?
classification model:
belongs_to :parent, class_name: "Classification", optional: true
has_many :children, class_name: "Classification", foreign_key: "parent_id", dependent: :destroy
has_many :class_fields
has_many :fields, through: :class_fields, source: :classification_field
accepts_nested_attributes_for :fields, allow_destroy: true
has_closure_tree
classification_field model:
has_many :class_fields
has_many :classifications, through: :class_fields
class_fields model:
belongs_to :classification
belongs_to :classification_field
Form where I am rendering dynamic form fields based on the classification fields details:
<%= form.fields_for :properties, OpenStruct.new(#sr.properties) do |builder| %>
<% #details.each do |field| %>
<%= render "srs/fields/#{field.field_type}", field: field, form: builder %>
<% end %>
<% end %>
Schema:
enable_extension "plpgsql"
create_table "class_fieldmembers", force: :cascade do |t|
t.integer "classification_id"
t.integer "classification_field_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "class_fields", force: :cascade do |t|
t.bigint "classification_id", null: false
t.bigint "classification_field_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["classification_field_id"], name: "index_class_fields_on_classification_field_id"
t.index ["classification_id"], name: "index_class_fields_on_classification_id"
end
create_table "classification_fields", force: :cascade do |t|
t.string "name"
t.string "field_type"
t.string "required"
t.string "classification_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "displayname"
end
create_table "classification_hierarchies", force: :cascade do |t|
t.integer "ancestor_id", null: false
t.integer "descendant_id", null: false
t.integer "generations", null: false
t.index ["ancestor_id", "descendant_id", "generations"], name: "classification_anc_desc_idx", unique: true
t.index ["descendant_id"], name: "classification_desc_idx"
end
create_table "classifications", force: :cascade do |t|
t.string "name"
t.string "displayname"
t.text "description"
t.boolean "inuse"
t.integer "sort_order"
t.integer "parent_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "srs", force: :cascade do |t|
t.string "summary"
t.text "description"
t.string "status"
t.string "priority"
t.bigint "user_id", null: false
t.bigint "classification_id", null: false
t.text "properties"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["classification_id"], name: "index_srs_on_classification_id"
t.index ["user_id"], name: "index_srs_on_user_id"
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.boolean "admin"
t.string "first_name"
t.string "last_name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
add_foreign_key "class_fields", "classification_fields"
add_foreign_key "class_fields", "classifications"
add_foreign_key "srs", "classifications"
add_foreign_key "srs", "users"
Query results from console:
[1] pry(main)> ClassificationField.includes(:classifications).where(classification_id: [1, 6] )
ClassificationField Load (0.7ms) SELECT "classification_fields".* FROM "classification_fields" WHERE "classification_fields"."classification_id" IN ($1, $2) [["classification_id", "1"], ["classification_id", "6"]]
ClassificationField Load (0.6ms) SELECT "classification_fields".* FROM "classification_fields" WHERE "classification_fields"."classification_id" IN ($1, $2) /* loading for inspect */ LIMIT $3 [["classification_id", "1"], ["classification_id", "6"], ["LIMIT", 11]]
=> #<ClassificationField::ActiveRecord_Relation:0x4a10>
Any help is appreciated.
Try this. Convert query result to array of objects using .to_a
#details = ClassificationField.includes(:classifications).where(classification_id: [1, 6] ).to_a
I think I have it now.
#details = ClassificationField.joins(:class_fields).where(class_fields: {classification_id: [#parentids]}).to_a if params[:sub].present?

Associations for statistics

I'm new to RoR and I need some help with associations. I'm using rails 6.0.3.4 and ruby 2.7.0.
Users can create cases and cases belongs to a certain district. Districts belongs to a state. It has to be that way, because cases can't belongs to a state.
Now I want to show the number of cases for a certain diagnosis for each state. I have to use district, to get all the cases for a state. How should I build the where(...) condition?
<!-- State -->
<div class="card">
<div class="card-body">
<h5 class="card-title">State</h5>
<p><%= State.find(1).titel%> (<%= #diagnosis.cases.where(...).count %>)</p>
</div>
</div>
My Models
case.rb
class Case < ApplicationRecord
before_create :set_pseud
belongs_to :user
belongs_to :diagnosis
belongs_to :district
belongs_to :report, optional: true
end
district.rb
class District < ApplicationRecord
has_many :users
has_many :cases
has_many :reports
belongs_to :state
end
state.rb
class State < ApplicationRecord
has_many :districts
has_many :users
end
For better understanding my schema.rb:
ActiveRecord::Schema.define(version: 2021_02_11_140244) do
create_table "cases", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.string "gender"
t.date "birthdate"
t.string "place_of_residence"
t.string "diagnosis"
t.bigint "user_id"
t.datetime "confirmed_at"
t.datetime "created_at", precision: 6
t.datetime "updated_at", precision: 6, null: false
t.bigint "diagnosis_id"
t.bigint "district_id"
t.bigint "report_id"
t.string "pseud"
t.index ["diagnosis_id"], name: "index_cases_on_diagnosis_id"
t.index ["district_id"], name: "index_cases_on_district_id"
t.index ["pseud"], name: "index_cases_on_pseud"
t.index ["report_id"], name: "index_cases_on_report_id"
t.index ["user_id"], name: "index_cases_on_user_id"
end
create_table "diagnoses", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "illness"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "districts", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "name"
t.string "place"
t.integer "postal_code"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.bigint "state_id", null: false
t.index ["state_id"], name: "index_districts_on_state_id"
end
create_table "reports", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
t.bigint "district_id"
t.text "comment"
t.datetime "date"
t.bigint "user_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["district_id"], name: "index_reports_on_district_id"
t.index ["user_id"], name: "index_reports_on_user_id"
end
create_table "states", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "titel"
t.string "abbr"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "role"
t.string "first_name"
t.string "last_name"
t.bigint "district_id"
t.bigint "state_id"
t.index ["district_id"], name: "index_users_on_district_id"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
t.index ["state_id"], name: "index_users_on_state_id"
end
end
You should add a further association into state:
has_many :cases, through: :districts
Rather than finding your state in the view, you should do that in the controller and pass it to the view in an instance variable:
#state = State.find(params[:id])
I've assumed you're using a show action here rather than manually coding the state ID for some reason.
You can then do something like this:
#state.cases.where(diagnoses: { id: #diagnosis.id }).count
Or if you prefer, you can skip the .id on #diagnosis:
#state.cases.where(diagnoses: { id: #diagnosis }).count

Can we have multiple foreign key in active record schema?

I have an schema that has person table, email table, phone table and address table.
Person model
class Person< ApplicationRecord
has_many :emails, dependent: :destroy
accepts_nested_attributes_for :emails
default_scope { order(created_at: :desc) }
end
Email Model
class Email< ApplicationRecord
belongs_to :Person
has_one :phone, dependent: :destroy
has_many :address, dependent: :destroy
accepts_nested_attributes_for :phone
accepts_nested_attributes_for :address
end
Phone Model
class Phone< ApplicationRecord
belongs_to :Email
end
Address Model
class Address < ApplicationRecord
belongs_to :Email
end
My schema looks like this
ActiveRecord::Schema.define(version: 2019_06_03_231058) do
create_table "emails", id: :string, limit: 36, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci", force: :cascade do |t|
t.boolean "deleted", default: false, null: false
t.datetime "created_at", precision: 3, null: false
t.datetime "updated_at", precision: 3, null: false
t.string "Person_id", limit: 36
t.index ["Person_id", "created_at"], name: "index_email_on_Person_id_and_created_at"
end
create_table "phones", id: :string, limit: 36, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci", force: :cascade do |t|
t.string "phone_id", limit: 36, null: false
t.boolean "deleted", default: false, null: false
t.datetime "created_at", precision: 3, null: false
t.datetime "updated_at", precision: 3, null: false
t.string "email_id", limit: 36
t.string "person_id", limit: 36
t.index ["email_id", "created_at"], name: "index_phone_on_email_id_and_created_at"
t.index ["person_id"], name: "fk_rails_7119a1d90f"
end
create_table "persons", id: :string, limit: 36, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci", force: :cascade do |t|
t.boolean "deleted", default: false, null: false
t.datetime "created_at", precision: 3, null: false
t.datetime "updated_at", precision: 3, null: false
t.index ["created_at"], name: "index_persons_on_created_at"
end
create_table "address", id: :string, limit: 36, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci", force: :cascade do |t|
t.string "address_id", limit: 36, null: false
t.boolean "deleted", default: false, null: false
t.datetime "created_at", precision: 3, null: false
t.datetime "updated_at", precision: 3, null: false
t.string "email_id", limit: 36
t.string "person_id", limit: 36
t.index ["email_id", "created_at"], name: "index_address_on_email_id_and_created_at"
t.index ["person_id"], name: "fk_rails_485c78b376"
end
add_foreign_key "emails", "persons"
add_foreign_key "phones", "emails"
add_foreign_key "phones", "persons"
add_foreign_key "address", "emails"
add_foreign_key "address", "persons"
end
So if you notice in my schema at very end I have 2 foreign keys for phones and address.
when I insert data email_id is placed in person table but not person_id.
I see same issue in address table as well where email_id is placed but not person_id
I am new to rails Active record concept when through online documentation couldn't really solve this issue any help is much appreciated.

ActiveRecord query with multiple joins not recognizing the relations

I am trying to write an ActiveRecord Query that returns all students enrolled in a certain course with the following query:
def self.students_enrolled_in(course_id)
Student
.joins(:enrollments)
.joins(:sections)
.joins(:courses)
.where(sections: { course_id: course_id })
end
the result in the rails console is:
ActiveRecord::ConfigurationError: Can't join 'Student' to association named 'sections'; perhaps you misspelled it?
it seems that the association is made. what am I doing wrong? does the query actually mean that all the join() statements have to relate back to Student, or should ac trace out the relational links?
Professor show page:
<div class="col-md-8">
<h2 class="card-title"><%= #professor.name %></h2>
<% #courses_taught.each do |course| %>
<div class="card mb-4 card-header">
<img class="card-img-top" src="http://placehold.it/750x300" alt="Card image cap">
<h3 class="card-text"><%= course.title %></h3>
</div>
<div class="card-body">
<% course.sections.enrollments.students.each do |student| %>
<p><% student.name %></p>
<% end %>
</div>
<% end %>
</div>
models:
enrollment
class Enrollment < ApplicationRecord
belongs_to :section
belongs_to :student
end
Student:
class Student < ApplicationRecord
has_many :enrollments
end
Professor:
class Section < ApplicationRecord
has_many :enrollments
belongs_to :professor
belongs_to :course
validates_uniqueness_of :professor_id, scope: :course_id
scope :by_professor_id, ->(prof_id) { where('professor_id = ?', prof_id) }
end
Course:
class Course < ApplicationRecord
enum status: { planning: 0, offered: 1 }
scope :offered, -> { where(status: 1) }
scope :planning, -> { where(status: 0) }
belongs_to :department
has_many :sections
has_many :professors, through: :sections
validates :title, :number, :status, :description, presence: true
validates :description, length: { in: 10..500 }
validates :title, :number, uniqueness: { case_sensitive: false }
def self.search(term)
if term
where('title LIKE ?', "%#{term}%").order('title DESC')
else
order('title ASC')
end
end
def self.taught_by(professor_id)
Course
.joins(:sections)
.joins(:professors)
.where(sections: { professor_id: professor_id })
.select('distinct courses.*')
end
end
Schema:
ActiveRecord::Schema.define(version: 20171013201907) do
create_table "courses", force: :cascade do |t|
t.string "title"
t.text "description"
t.string "number"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "status", default: 0
t.integer "department_id"
t.index ["department_id"], name: "index_courses_on_department_id"
end
create_table "departments", force: :cascade do |t|
t.string "name"
t.text "description"
t.text "main_image"
t.text "thumb_image"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "enrollments", force: :cascade do |t|
t.integer "section_id"
t.integer "student_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["section_id"], name: "index_enrollments_on_section_id"
t.index ["student_id"], name: "index_enrollments_on_student_id"
end
create_table "professors", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "status", default: 0
t.integer "department_id"
t.text "bio"
t.index ["department_id"], name: "index_professors_on_department_id"
end
create_table "sections", force: :cascade do |t|
t.integer "number"
t.integer "max_enrollment"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "professor_id"
t.integer "course_id"
t.string "room"
t.index ["course_id"], name: "index_sections_on_course_id"
t.index ["professor_id", "course_id"], name: "index_sections_on_professor_id_and_course_id", unique: true
t.index ["professor_id"], name: "index_sections_on_professor_id"
end
create_table "students", force: :cascade do |t|
t.string "name"
t.decimal "gpa"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "name"
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "roles"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
end
Another way to do this is to add some more associations to your Student model:
class Student < ApplicationRecord
has_many :enrollments
has_many :sections, through: :enrollments
has_many :courses, through: :sections
scope :enrolled_in_course, -> (course) { joins(:sections).where(course_id: course.id)
end
You can then find all students enrolled in a course with:
Student.enrolled_in_course(course)
You're over-applying .joins. Try starting from the inside out. First, find the course:
Course.find_by(id: course_id)
Then, find all the sections associated with the course. No need to do a joins here:
Section.where(course: Course.find_by(id: course_id))
Now you do your join:
Student.joins(:enrollments).where(enrollments: {section: Section.where(course: Course.find_by(id: course_id))})
I think that ought to do the trick for you. But, untested. So, give it a go and see if it works.
P.S.: Try posting only the most relevant code. It's not so much fun to sort through a bunch of extraneous stuff.

Create object on IRB

I'm trying to create an object "lending" on irb to test my database and table connections but I can't.
I have successfully if I specify the :customer_id => 1 on the creation command.
The customer_id field in the database table doesn't settled as NOTNULL.
Could anyone help me?
This is the command I'm trying and the error:
irb(main):004:0> emprestimo = Emprestimo.create(:valor => 10000.00, :qnt_parcelas => 10, :valor_parcelas => 1000.00, :banco => 'Bic', :corretora => 'milreais')
(0.2ms) BEGIN
(0.2ms) ROLLBACK
=> #<Emprestimo id: nil, cliente_id: nil, valor: 10000.0, qnt_parcelas: 10, valor_parcelas: 1000.0, data_emprestimo: nil, banco: "Bic", corretora: "milreais", created_at: nil, updated_at: nil>
My /db.schema.rb:
ActiveRecord::Schema.define(version: 20170208154641) do
create_table "clientes", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
t.string "nome", limit: 45, null: false
t.string "cpf", limit: 14, null: false
t.string "rg", limit: 15, null: false
t.string "matricula", limit: 20, null: false
t.string "senha", limit: 10
t.date "data_nasc"
t.string "orgao", limit: 30
t.string "tel", limit: 15, null: false
t.string "tel2", limit: 15
t.string "convenio", limit: 10, null: false
t.string "email", limit: 35
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "emprestimos", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
t.integer "cliente_id"
t.float "valor", limit: 24, null: false
t.integer "qnt_parcelas", limit: 3, null: false
t.float "valor_parcelas", limit: 24, null: false
t.date "data_emprestimo"
t.string "banco", limit: 40, null: false
t.string "corretora", limit: 40
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "enderecos", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
t.integer "cliente_id"
t.string "rua", limit: 45, null: false
t.bigint "numero", null: false
t.string "complemento", limit: 45, null: false
t.string "bairro", limit: 45, null: false
t.string "cidade", limit: 45, null: false
t.string "estado", limit: 2, null: false
t.string "cep", limit: 9, null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "operadors", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
t.string "user", limit: 45
t.string "senha", limit: 6
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
My Cliente and Emprestimo models:
class Emprestimo < ApplicationRecord
belongs_to :cliente
end
class Cliente < ApplicationRecord
has_one :endereco
has_many :emprestimos
end
Thank you very much.
Actually, in Rails 5, belongs_to relationship now is required by default. It basically adds a presence validator in your foreing key.
You can disable this behavior adding optional: true as belongs_to argument, like this:
belongs_to :cliente, optional: true
From the docs:
4.1.2.11 :optional
If you set the :optional option to true, then the presence of the associated object won't be validated. By default, this option is set to false.

Resources