I have a model Member that has a new creation form. The form allows users to assign a department and position for each member to be a part of. The positions are relative to the department. In a separate part of the app, users can create departments and create/assign positions. I am trying to create a grouped_collection_select for the new members page, however my positions are not showing up, just departments as categories. I believe this is an association issue, where the positions are not being associated with their respective dept. I have the string department_id in my positions model, however I don't think the selection is able to read that as the parent. If anyone can point me in the correct direction that'd be awesome.
The line giving an error: (from the new members form_for)
<%= f.grouped_collection_select :title, Department.where(production_id: current_user.default_working_production_id).order(:department), :positions, :department, :id, :position, include_blank: true %>
My schema looks like:
create_table "departments", force: true do |t|
t.string "department"
t.datetime "created_at"
t.datetime "updated_at"
t.string "production_id"
end
create_table "positions", force: true do |t|
t.string "position"
t.string "department_id"
t.datetime "created_at"
t.datetime "updated_at"
t.string "production_id"
end
My model associations:
class Member < ActiveRecord::Base
belongs_to :company
validates :firstname, presence: true
validates :email, presence: true
def name
"#{firstname} #{lastname}"
end
end
class Department < ActiveRecord::Base
has_many :positions
attr_accessible :department
validates :department, presence: true
end
class Position < ActiveRecord::Base
belongs_to :department
attr_accessible :department_id, :position, :department
end
The primary keys (id) of each Model are integers, but the foreign keys for the associations are defined in your migrations as strings. (department_id, production_id). This may be causing problems when Rails tries to make the associations because for example, "1" == 1 evaluates to false. Change the foreign keys to integers via a new migration or by editing the existing migration and resetting the db.
You can confirm if you've fixed the association with the rails console:
$> rails console
Running via Spring preloader in process 20933
Loading development environment (Rails 4.2.5)
irb(main):001:0> Department.first.positions
This will query the First department in the db for all of its positions. If it throws an error then the association is not setup properly. If it returns a collection of positions, the association works.
Related
I'm creating an expense tracker application using Ruby on Rails 7.0. I have 3 models Account, Category, and Transaction.
This is how transactions migration looks:
class CreateTransactions < ActiveRecord::Migration[7.0]
def change
create_enum :transaction_type, %w[debit credit]
create_table :transactions do |t|
t.datetime :date
t.string :description
t.enum(:transaction_type, enum_type: 'transaction_type', null: false)
t.decimal :amount
t.string :notes
t.references :account, null: false, foreign_key: true
t.references :category, null: false, foreign_key: true
t.timestamps
end
end
end
Below is the Transaction model.
class Transaction < ApplicationRecord
belongs_to :account
belongs_to :category
enum :transaction_type, { debit: 'DEBIT', credit: 'CREDIT' }, prefix: true
end
I followed this video tutorial and defined enums that way. But when I hang around with the Transaction model on the rails console, it gives me this error Object doesn't support #inspect error
For example, Transaction.transaction_type_debit should return all the transactions with transaction_type of debit since prefix: true enables those methods. But it gives me the above error instead.
I suspect there's something with the associations with the other two models but still not sure exactly why and how to fix it.
Finally, I figured out that the issue is with irb. What I did was just added gem 'pry-rails' and it replaced irb with pry. So, I'm not getting the error anymore with pry.
Please how can I reference a table when not using the default table id as the table's primary key? I created two tables one having email as the primary key and I want to have this table email as the foreign key in the other table. Please How can i achieve that?
You may create table with email as primary key like this:
create_table :users, id: false do |t|
t.string :email, primary_key: true
t.string :name
t.timestamps
end
create_table :posts do |t|
t.string :title
t.text :body
t.string :user_email
t.timestamps
end
And define your models like this:
class User < ActiveRecord::Base
self.primary_key = 'email'
has_many :posts, foreign_key: :user_email
end
class Post < ActiveRecord::Base
belongs_to :user, foreign_key: :user_email
end
That's all you need to do. Also you may keep id as primary key for User model but use use email as foreign key - this may be easier way to handle your models.
I m getting unreadable values # dropdown menu in active admin.
I have an attribute which has a inclusion of specific values(around 10 values) but when I am making a new object of that class by using active admin... firstly it is showing the unreadable drop down menu
second its showing that attribute to be blank even if I m choosing some unreadable value..
plz help
my admin/Resident.rb page: :
ActiveAdmin.register Resident do
permit_params :room_number,:roll_number,:name,:hostel,:hostel_id
index do
column :room_number
column :roll_number
column :name
column :hostel
actions
end
filter :name,:as => :string
filter :hostel, :as => :select
filter :room_number
filter :roll_number
form do |f|
f.semantic_errors *f.object.errors.keys
inputs 'Enter the student details' do
input :room_number
input :roll_number
input :name
input :hostel
actions
end
end
end
I have two models : Hostel And Resident :
models/hostel.rb
class Hostel < ActiveRecord::Base
has_many :residents
end
models/resident.rb
class Resident < ActiveRecord::Base
belongs_to :hostel
validates :room_number,presence: true,uniqueness: {case_sensitive: false}
validates :roll_number,presence: true,uniqueness:{case_sensitive: false}
validates :name, presence: true,length:{ maximum: 50 }
validates :hostel,presence: true
def display_name
hostel
end
end
schema: :
Resident
create_table "residents", force: :cascade do |t|
t.string "room_number"
t.string "roll_number"
t.string "name"
t.string "hostel"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "hostel_id"
end
Hostel:
create_table "hostels", force: :cascade do |t|
t.string "hostel"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
For making the text readable, you can reimplement the "to_s" method :
class Hostel < ActiveRecord::Base
#...
def to_s
self.name
end
end
But active admin is smart enough to use the "name" row if existing usually. The bad side of this method is everywhere in your log etc. it will use the name. Something like [self.id,self.name].join('-') seems better for debugging if the name field of your table hostels is not unique.
Your second problem is caused by one of theses two things:
Check your params permits, and allow "hostel_id"
Ensure your <select name="model[hostel_id]" > and not <select name="model[hostel]">. This should be done automatically, if not it's probably because you didn't defined well the link has_many / belongs_to in your two models.
Finally, the last way is you can still push your own collection as parameter of the f.input into the active admin:
f.input :hostel_id, collection: Hostel.all.map{|x| [x.name, x.id]}
One more time, this should be done automatically. In your case it's not, so look closely your db schema.
Happy Coding,
Yacine.
class Hostel < ActiveRecord::Base
def display_name
name # or that code will return a representation of your Model instance
end
end
in place of name use the column name whose value u want to be displayed in drop down
Let's say I have
class CreateAppointments < ActiveRecord::Migration
def change
create_table :physicians do |t|
t.string :name
t.timestamps null: false
end
create_table :patients do |t|
t.string :name
t.timestamps null: false
end
create_table :appointments do |t|
t.belongs_to :physician, index: true
t.belongs_to :patient, index: true
t.datetime :appointment_date
t.timestamps null: false
end
end
end
1- Do I have to define again the associations on the model file? which leads me to my next question....
2- Do I have to create a model for this third table of appointments or just run the migration and the Active Record will take care of updating it everytime a doctor and a patient updates? when will the insert to this third table will be triggered in this type of association?
There is alot of magic inside of active record, so i understand where you are coming from.
Yes, The migration will not add the proper associations to your ActiveRecord models. Migrations are there to make changes to the database.
Yes, if you did not generate this using rails g scaffold or model, then you will need to create an Appointment class that inherits from ActiveRecord::Base in order to work with it through the orm. Then put the proper associations on them (patients have many appointments, they would also have many doctors through appointments. vice versa for doctors.
I'm trying to understand how rails works in respect to foreign key and primary keys. Coming from a pure SQL background the Rails method seems very alien to me.
I have the following two migrations:
Groups
class CreateGroups < ActiveRecord::Migration
def self.up
create_table :groups do |t|
t.string :title
t.text :description
t.string :city
t.integer :event_id
t.string :zip
t.string :group_id
t.text :topics
t.timestamps
end
end
def self.down
drop_table :groups
end
end
and Events:
class CreateEvents < ActiveRecord::Migration
def self.up
create_table :events do |t|
t.string :title
t.string :description
t.string :city
t.string :address
t.time :time_t
t.date :date_t
t.string :group_id
t.timestamps
end
end
def self.down
drop_table :events
end
end
A Group can have many events and an event can belong to a single group. I have the following two models:
class Event < ActiveRecord::Base
belongs_to :group, :foreign_key => 'group_id'
end
and
class Group < ActiveRecord::Base
attr_accessible :title, :description, :city, :zip, :group_id, :topics
has_many :events
end
not sure how to specify foreign keys and primary keys to this. For example a group is identified by the :group_id column and using that I need to fetch events that belong to a single group!
how do i do this!
I see you have group_id and event_id as strings in your migration, so I think you might be missing a rails convention. The rails convention is that all tables have a primary key named id of type integer, and any foreign keys reference it by the name of the model, singular, + _id:
table groups:
id: integer
name: string
table events:
id: integer
name: string
group_id: integer
From this convention, all you have to specify in your models is:
class Event < ActiveRecord::Base
belongs_to :group
end
class Group < ActiveRecord::Base
has_many :events
end
At this point, rails knows what to do by convention over configuration: To find an event's group, it knows to look for group_id (singular) to refer to groups.id (plural table name)
event = Event.first #=> returns the first event in database
group = event.group #=> returns the group object
Similarly, it know how to find all the events in a group
group = Group.first #=> returns first group in database
group.events #=> returns an Enumerable of all the events
For more reading, read the rails guide on associations