"Hello everyone" I'm practicing a little bit with rails right now and I'm having issues understanding how to access data with associations. Currently I have 3 tables, Doctors, Patients and Appointments.
class CreateDoctors < ActiveRecord::Migration
def change
create_table :doctors do |t|
t.string :name
t.timestamps null: false
end
end
end
class CreatePatients < ActiveRecord::Migration
def change
create_table :patients do |t|
t.string :name
t.timestamps null: false
end
end
end
class CreateAppointments < ActiveRecord::Migration
def change
create_table :appointments do |t|
t.date :date_appointment
t.references :doctor, index: true, foreign_key: true
t.references :patient, index: true, foreign_key: true
t.timestamps null: false
end
end
end
With this I'm trying to create a form to insert record on Appointments table, this way I can access and get the names for either doctors or patients after submitting the form.
<%= form_for(#appointment) do |f| %>
<%= f.label :date, "Choose a date for your appointment" %>
<%= f.collection_select(:doctor_id, Doctor.all, :id, :name, prompt: true) %>
<%= f.submit %>
<% end %>
The data is being inserted, but when I call the Show "Template" is giving me an error saying that the parameter for doctor in "Nil" even though it has a value.
<%= #appointment.doctor.name %>
And here's the appointment controller data
class AppointmentsController < ApplicationController
def index
end
def show
end
def new
#appointment = Appointment.new
end
def create
#appointment = Appointment.new(appointment_params)
if #appointment.save
redirect_to #appointment
else
render "New"
end
end
private
def appointment_params
params.require(:appointment).permit(:date, :doctor_id, :patient_id)
end
def find_appointment
#appointment = Appointment.find(params[:id])
end
end
What I want to do is basically be able to render or show the names of doctors or patients according to the value of the attributes on the row that is being created after creating a new row with the form.
class Appointment < ActiveRecord::Base
belongs_to :doctor
belongs_to :patient
end
class Doctor < ActiveRecord::Base
has_many :appointments
has_many :patients, through: :appointments
end
class Patient < ActiveRecord::Base
has_many :appointments
has_many :doctors, through: :appointments
end
Thank you for your time!
Maybe I'm missing something but aren't you forgetting to set the #appointment var?
def show
#appointment = Appointment.find(params['id'])
end
(should work if you have a route for this)
Related
I'm building a sinatra app with Active record. The idea is to essentially have a custom email app. Here I have the models User and Message. A User has_many :messages and a Message belongs_to :user. This may be where I have the issue. I also have it set up for a Message belongs_to :user and has_many :users.
here are the models
Now when I create a message in the action controller I am attempting to use the shove methods to put the new message in a user's messages array. If I attempt to "share" this message with multiple users at once with all the user's id's in params( #user = User.find(id) and then user.messages << #new_message) the last user will have the message stored in it's .messages array. However only the last one to be iterated.
class Message < ActiveRecord::Base
belongs_to :user
has_many :users
end
class User < ActiveRecord::Base
validates :username, presence: true, uniqueness: true
has_secure_password
has_many :messages
end
The idea is the writer "owns" the message but can share it with many users. Here are the tables
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :username
t.string :email
t.string :password_digest
end
end
end
class CreateMessages < ActiveRecord::Migration
def change
create_table :messages do |t|
t.string :message
t.string :author
t.integer :user_id
t.integer :user_ids
t.integer :share_id
t.string :title
t.timestamps
end
end
end
# action controller
new_params = {}
new_params[:message] = params["message"]
new_params[:title] = params["title"]
new_params[:author] = params["author"]
new_params[:user_id] = params["user_id"]
#message = Message.create(new_params)
# #share = Share.create
# #message.share_id = #share.id
response.map do |x|
x.messages << #message
x.save!
end
#all = User.all
#user = User.find_by(username: #message.author)
erb :"/user/sent"
I am fairly sure this is because my associations are not set up properly.
You need to have has-and-belongs-to-many relationship between users and messages to implement sharing multiple messages to multiple users. Create an additional record, e.g. MessageShare and do has many to it from both sides:
class MessageShare < ActiveRecord::Base
belongs_to :user
belongs_to :message
end
class Message < ActiveRecord::Base
has_many :message_shares
end
class User < ActiveRecord::Base
has_many :message_shares
end
message_shares table should have user_id and message_id integer columns.
I have my resources:
resources :flows do
resources :fmodules
end
the new method in fmodules controller:
# /flows/1/fmodules/new
def new
#flow = Flow.find(params[:flow_id])
#fmodule = #flow.fmodules.build
end
the models:
class Flow < ApplicationRecord
has_many :fmodules, dependent: :destroy
validates :code, presence: true, length: { maximum: 5 }
validates :name, presence: true
end
class Fmodule < ApplicationRecord
belongs_to :flow
end
When i try to go at /flows/1/fmodules/new ruby says unknown attribute 'flow_id' for Fmodule.
I dont know what is wrong
Here is the migration of Fmodel in addition
class CreateFmodules < ActiveRecord::Migration[5.1]
def change
create_table :fmodules do |t|
t.string :code
t.string :name
t.string :f_code
t.timestamps
end
add_foreign_key :fmodules, :flows, column: :f_code
end
end
So, the problem is that you don't have a flow_id in your fmodules table. In rails, by convention the foreign key is build automatically inferring column name from an argument you pass to belongs_to. That's why rails think that foreign key for flows table is flow_id and it raises exception not finding it. You can overwrite the default with foreign_key option like the following
class Fmodule < ApplicationRecord
belongs_to :flow, foreign_key: : f_code
end
I am trying to create an association between a User model and an Attendance model in which an attendee_id references a user. The association is a many to many relationship between users and concerts. The join table attendances has two fields
:attendee and :concert.
seed.rb file:
require 'faker'
Concert.destroy_all
User.destroy_all
Attendance.destroy_all
15.times do
Concert.create(band: Faker::RockBand.name, venue: "#{Faker::LordOfTheRings.location}", date: Faker::Date.forward(rand(30)), start_time: "8:00 PM")
end
5.times do |number|
User.create(first_name: Faker::Name.first_name, last_name: Faker::Name.last_name, email: "#{number}#email.com", password: "password")
end
concerts = Concert.all
users = User.all
15.times do
Attendance.create(attendee: users.sample, concert: concerts.sample)
end
Here are the models:
class Attendance < ApplicationRecord
belongs_to :attendee, class_name: "User"
belongs_to :concert
end
class Concert < ApplicationRecord
validates :band, :venue, :date, :start_time, presence: true
has_many :attendances
has_many :attendees, through: :attendances
end
class User < ApplicationRecord
validates :first_name, :last_name, :email, presence: true
validates_format_of :email, with: /#/
has_secure_password
has_many :attendances, foreign_key: :attendee_id
has_many :concerts, through: :attendances
end
Here are the migrations:
class CreateAttendances < ActiveRecord::Migration[5.0]
def change
create_table :attendances do |t|
t.references :attendee
t.references :concert, index: true
t.timestamps
end
end
end
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
t.string :first_name
t.string :last_name
t.string :email
t.string :password_digest
t.timestamps
end
end
end
class CreateConcerts < ActiveRecord::Migration[5.0]
def change
create_table :concerts do |t|
t.string :band
t.string :venue
t.datetime :date
t.time :start_time
t.timestamps
end
end
end
Looks like there are no attendee_id column
bundle exec rails db:reset (same as db:drop + db:create + db:migrate + db:seed)
And for tests bundle exec rails db:test:prepare
If it`s not solve the problem, i think, we need moar stacktraces)
I run bundle exec rake db:drop and then I created the database bundle exec rake db:create and bundle exec rake db:migrate I was then able to seed the database.
Please try to change t.references to special alias t.belongs_to.
It worked for me with Rails 5.2.1
i'm learning Rails and i'm doing an exercise to practice associations and migration files.
Currently, trying to make a models between users, auction item, and bids.
So far for the migrate files I have the following:
class CreateItem < ActiveRecord::Migration
def change
create_table :auction do |t|
t.string :item_name
t.string :condition
t.date :start_date
t.date :end_date
t.text :description
t.timestamps
end
end
end
class CreateBids < ActiveRecord::Migration
def change
create_table :bids do |t|
t.integer :user_id
t.integer :auction_id
t.timestamps
end
end
end
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :email
t.string :username
t.string :password_digest
t.timestamps
end
end
end
These are the following models:
class Bid < ActiveRecord::Base
belongs_to :bidder, class_name: "User", foreign_key: "bidder_id"
belongs_to :auction
end
class User < ActiveRecord::Base
has_many :bids
has_many :auctions, :foreign_key => 'bidder_id'
has_secure_password
end
class Auction < ActiveRecord::Base
belongs_to :seller, class_name: "User", foreign_key: :user_id
has_many :bids
has_many :bidders, through: :bids
end
Any suggestions or opinions? I'm currently trying to test the tables but auctions doesn't seem to be working...
Specifically, my auction table can't seem to find a user_id and therefore a user doesn't have any auctions.
foreign_key refers to the _id (by default) or any unique attribute used to associate the models.
I can't see bidder model, you need to replace them with user_id as they are associated to user model.
Refer for more details belongs_to
class CreateBids < ActiveRecord::Migration
def change
create_table :bids do |t|
t.integer :user_id **do not think this is correct**
t.integer :auction_id **or this one**
t.timestamps
end
end
end
You want to use something more along the lines of the following
class CreateGames < ActiveRecord::Migration[5.0]
def change
create_table :games do |t|
t.integer :total_time
t.references :version, foreign_key: true **#this is how a foreign key should be declared**
t.integer :total_points
t.timestamps
end
end
end
Alternatively, if you want to change things in future migrations you can always add a reference:
def change
add_reference :levels, :version, foreign_key: true
end
I am getting the following error while inserting the data into database through rails console using ROR.
Error:
irb(main):004:0> book.comments << comment
(1.0ms) begin transaction
(0.0ms) rollback transaction
ActiveModel::MissingAttributeError: can't write unknown attribute `book_id`
from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4
.2.5.1/lib/active_record/attribute.rb:138:in `with_value_from_database'
from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4
.2.5.1/lib/active_record/attribute_set.rb:39:in `write_from_user'
from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4
.2.5.1/lib/active_record/attribute_methods/write.rb:74:in `write_attribute_with_
type_cast'
Here I am trying to link one table (comments) with another table (books) by inserting some data. My code flow is below:
irb(main):004:0>book=Book.find(1)
comment = Comment.new :text => "This is an comment", :author => "Adam"
book.comments << comment
.......create_comments.rb:
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.text :text
t.string :author
t.timestamps null: false
end
end
end
book.rb:
class Book < ActiveRecord::Base
has_many :comments
end
comment.rb:
class Comment < ActiveRecord::Base
belongs_to :book
end
While I am executing the last line this error is coming.
You have not book_id column in your comments table.
Follow this below steps:
rails g migration AddBookToComments book:references
which will create a migration file as:
class AddBookToComments < ActiveRecord::Migration
def change
add_reference :comments, :book, index: true, foreign_key: true
end
end
run rake db:migrate
add book_id in strong paremeters in comments_controller.rb
Then try:
> book=Book.find(1)
> comment = book.comments.new(:text => "This is an comment", :author => "Adam")
> comment.save!