how to get records using join between tables - sql

i have doctors table and a users table such that user belongs_to doctor and doctor has_one user as profile. (polymorphic relation)
i want data from doctors table as well as users table where doctor.id = users.profile_id
#search_query = params[:doctor][:query]
#users = User.select("profile_id, username").where("username like ? OR address like ?", #search_query, #search_query )
#doctor = Doctor.select("doctors.start_time, doctors.end_time, doctors.detail, doctors.experience, doctors.license_number, doctors.fee, doctors.available_days, doctors.specialization, doctors.mission_statement, doctors.id, users.id AS user_id, users.name, users.email, users.username, users.address, users.age, users.gender").joins(:user).where("? = doctors.id", #users.each do |u| u.profile_id end)#.joins(:user).where(:users => {:users.profile_id => #doctor.id})
Doctors' migration
create_table(:users) do |t|
## Database authenticatable
t.string :email, :null => false, :default => ""
t.string :encrypted_password, :null => false, :default => ""
t.string :username, :null => false
t.string :address
t.integer :age
t.string :gender
t.string :name
t.integer :profile_id
t.string :profile_type
Users' migration
class CreateDoctors < ActiveRecord::Migration
def change
create_table :doctors do |t|
t.time :start_time
t.time :end_time
t.text :detail
t.integer :experience
t.text :mission_statement
t.string :license_number
t.integer :fee
t.string :available_days
t.string :specialization
t.timestamps
end
end
end

Doctor.joins("LEFT OUTER JOIN users ON doctors.id = users.profile_id")

Related

How to write the active record query

I have three models in context of this question:
class ClearanceBatch < ActiveRecord::Base
has_many :items
belongs_to :user
end
class Item < ActiveRecord::Base
belongs_to :style
belongs_to :user
belongs_to :clearance_batch
validates :id, :uniqueness => true
end
class User < ActiveRecord::Base
has_many :items, dependent: :destroy
has_many :clearance_batches, dependent: :destroy
enum role: {staff: 0, vendor: 1, admin: 2}
end
Schema:
create_table "clearance_batches", force: :cascade do |t|
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "status", default: false
t.string "boughtby", default: ""
t.integer "user_id"
end
add_index "clearance_batches", ["user_id"], name: "index_clearance_batches_on_user_id"
create_table "items", force: :cascade do |t|
t.string "size"
t.string "color"
t.string "status"
t.decimal "price_sold"
t.datetime "sold_at"
t.integer "style_id"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "clearance_batch_id"
t.integer "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.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.integer "role", default: 0
end
I want to find all items in a batch of the currently logged in user(mainly vendor) with the status "clearanced", and get their details in a loop from controller to my view
Can anyone please help me out with the active record query? Please! :)
The SQLite Query I think would be:
Select I.id from clearance_batches C INNER JOINS Items I on C.id = I.clearance_batch_id where C.user_id = "1" and I.status = "clearanced"
(If 1 is the current user, keeping in mind I am only allowing user of role vendors to be a user in clearance_batch table)
(1) Query:
Items.where(status: "clearanced")
.joins(:clearance_batches)
.where(clearance_batches: {user_id: current_user})
(2) Controller:
#clearanced_items = query(1)
(3) View:
<% #clearanced_items.each do |c_item| %>
...
<% end %>

Converting a SQL query to Active Record in Rails 4

Here are my two models
class Comment < ActiveRecord::Base
belongs_to :phone
end
class Phone < ActiveRecord::Base
has_many :comments, :dependent => :destroy
end
Here is the schema for the tables
ActiveRecord::Schema.define(version: 20131119231249) do
create_table "comments", force: true do |t|
t.string "username"
t.string "ipaddy"
t.text "pcomments"
t.string "company"
t.string "calltype"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "pnumber"
t.string "source"
end
create_table "phones", force: true do |t|
t.integer "pnumber"
t.text "mrcomment"
t.integer "ccount"
t.datetime "created_at"
t.datetime "updated_at"
end
end
Here is the raw SQL that works
SELECT phones.ccount ,
comments.*
FROM phones
INNER JOIN comments
ON phones.pnumber = comments.pnumber;
When I run the following in my controller
#phones = Phone.select("phones.ccount, comments.*").joins(:comments).where(:comments => {comments.pnumber => phones.pnumber})
I get the following error
undefined local variable or method `comments' for #<FrontPageController:0x00000003c56c70>
Any help on what the active record statement should like would be greatly appreciated
It seems like you're using the select() erroneously. Have you read the docs: http://apidock.com/rails/ActiveRecord/QueryMethods/select ?
from docs: "Second: Modifies the SELECT statement for the query so that only certain fields are retrieved:"
The query's syntax should more look like (using a standard example):
l = Location.where(["id = ?", id]).select("name, website, city").first.

rails no such column error

I have the following app. A Movie has many reviews, a moviegoer has many reviews.
When I try to associate a review with a movie I get the following error
Review Load (0.1ms) SELECT "reviews".* FROM "reviews" WHERE "reviews"."movie_id" = 5
SQLite3::SQLException: no such column: reviews.movie_id: SELECT "reviews".* FROM "reviews" WHERE "reviews"."movie_id" = 5
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: reviews.movie_id: SELECT "reviews".* FROM "reviews" WHERE "reviews"."movie_id" = 5
after using a sql gui editor I found that the correct query should be
SELECT "reviews".* FROM "reviews" WHERE "movie_id" = 5
review.rb
class Review < ActiveRecord::Base
belongs_to :movie
belongs_to :moviegoer
attr_protected :moviegoer_id
end
movie.rb and moviegoer.rb have
has_many :reviews
in them.
schema.rb
ActiveRecord::Schema.define(:version => 20130222225620) do
create_table "moviegoers", :force => true do |t|
t.string "name"
t.string "provider"
t.string "uid"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "movies", :force => true do |t|
t.string "title"
t.string "rating"
t.text "description"
t.datetime "release_date"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "reviews", :force => true do |t|
t.integer "potatoes"
t.text "comments"
t.integer "moviegoers_id"
t.integer "movies_id"
end
end
What am I doing wrong? why is rails querying "reviews"."movie_id" instead of just "movie_id"?
You have the wrong column name in your migration. The rails convention is that foreign keys are to be singular. If they are not then you need to tell rails what the foreign key is with an options hash on the association.
Either rollback your migration, fix the column name (moviegoers_id is wrong as well) then migrate again, or tell rails the foreign key.
Class Review < ActiveRecord::Base
belongs_to :movie, :foreign_key => 'movies_id'
belongs_to :moviegoer, :foreign_key => 'moviegoers_id'
end
And the same has to happen on the has many side of both models.

has_many :through NameError: uninitialized constant

I just want to make a little join table, eventually storing extra info on that join (which is why I'm not using HABTM). From the rails documentation of associations I've created the following models:
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, :through => :appointments
end
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, :through => :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :physicians
belongs_to :patients
end
my schema looks like this:
ActiveRecord::Schema.define(:version => 20130115211859) do
create_table "appointments", :force => true do |t|
t.datetime "date"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "patient_id"
t.integer "physician_id"
end
create_table "patients", :force => true do |t|
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "physicians", :force => true do |t|
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
end
When I'm in the console and I create a physician and patient instance:
#patient = Patient.create!
#physician = Physician.create!
And try to associate one to the other
#physician.patients << #patient
I get
NameError: uninitialized constant Physician::Patients
Questions about this example have been asked before but none have address my scenario. Any ideas?
Thanks,
Neil, rails newbie.
The belongs_to calls in your Appointment model should take a singular form, not a plural form:
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
end

Why is the user_id not automatically added upon creation of a comment?

I have a field that creates a comment (named pcomment). I am trying to get it to automatically add the user_id to the pcomment in the pcomment table like it adds the purchase_id automatically. I am not sure why the purchase_id is being recorded in the database but the user_id remains blank for each pcomment. Here is the form for the pcomment.
<%= form_for([purchase, purchase.pcomments.build], :html => { :id => "blah_form" }) do |f| %>
<div class="field">
<h4>What deal are you offering?</h4>
<%= f.text_field :body %>
</div>
<% end %>
It may be that I have to add some hidden_field, but I don't think so. I am using http://ruby.railstutorial.org/book/ruby-on-rails-tutorial#cha-user_microposts as resource and in that the microposts dont have any hidden_field. Instead, the user_id is indexed and it automatically is created upon the creation of a micropost (based on who is signed in at the time). This part is working for me too, adding to my rational that indexing user_id on the pcomments table is enough to automatically generate it. Here is my schema.rb file so that you can see the current state of my database.
ActiveRecord::Schema.define(:version => 20121011085147) do
create_table "pcomments", :force => true do |t|
t.string "body"
t.integer "purchase_id"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "pcomments", ["purchase_id"], :name => "index_pcomments_on_purchase_id"
add_index "pcomments", ["user_id"], :name => "index_pcomments_on_user_id"
create_table "purchases", :force => true do |t|
t.string "content"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "purchases", ["user_id", "created_at"], :name => "index_purchases_on_user_id_and_created_at"
create_table "sales", :force => true do |t|
t.string "content"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "sales", ["user_id", "created_at"], :name => "index_sales_on_user_id_and_created_at"
create_table "scomments", :force => true do |t|
t.string "body"
t.integer "sale_id"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "scomments", ["sale_id"], :name => "index_scomments_on_sale_id"
add_index "scomments", ["user_id"], :name => "index_scomments_on_user_id"
create_table "users", :force => true do |t|
t.string "name"
t.string "email"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "password_digest"
t.string "remember_token"
t.boolean "admin", :default => false
end
add_index "users", ["email"], :name => "index_users_on_email", :unique => true
add_index "users", ["remember_token"], :name => "index_users_on_remember_token"
end
and the reason I know its not working is that I check in the database and the pcomment is successfully created with all columns filled in including purchase_id but the user_id is still blank. also, the user has_many pcomments and has_many purchases. The purchase has_many pcomments and belongs_to user. The pcomment belongs_to user and belong_to purchase.
also, here is the pcomments_controller.rb
class PcommentsController < ApplicationController
before_filter :signed_in_user
def create
#purchase = Purchase.find(params[:purchase_id])
#pcomment = #purchase.pcomments.build(params[:pcomment], :user_id => #purchase.user_id)
#pcomment.purchase = #purchase
if #pcomment.save
flash[:success] = "Offer submited!"
redirect_to :back
else
render 'shared/_pcomment_form'
end
end
def new
#pcomment=purchase.pcomments.new
end
end
def new
#pcomment=purchase.pcomments.new(:user_id => purchase.user_id)
end
end
purchase.pcomments.build builds empty Pcomment object just with purchase_id filled from purchase. To assign also user_id pass the hash with attribute:
purchase.pcomments.build(:user_id => purchase.user_id)