has_one association with user and customer and rails view form - ruby-on-rails

I've got the an has_one association:
has_one association user -> customer models
will the user have the customer_id or customer will have the user_id attribute?
other question: into my _form i'd like to have a select/option with all the users that hasn't associated with a customer which is the best way to do that?
thanks a lot.

The _id field is always in the model with the belongs_to, and refers to the other table name.
class Customer < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
has_one :customer
end
In this case, the customers table will have a user_id field.
For the second question, missing values are found in SQL using outer joins.
The SQL you want would be
select
from users
left outer join customers on users.id = customers.user_id
where customers.id is null
In ActiveRecord, add a scope to your User class.
In Rails 3.x:
class User < ActiveRecord::Base
has_one :customer
scope :missing_customer,
includes(:customer).where("customers.id is null")
end
In Rails 2.3.x:
class User < ActiveRecord::Base
named_scope :missing_customer,
{ :joins => "left outer join customers on users.id = customers.user_id",
:conditions => "customers.id is null" }
end

Related

Rails joins polymorphic model attribute where condition is met

I can't figure out how to make this query work. I'm looking to get all the user ids of addresses who have a user that is an admin.
Address
.near([#address.latitude, #address.longitude], 5)
.where(addressable_type: 'User')
.joins(:addressable)
.where('addressable.is_admin = ?', true)
.pluck(:id)
Address.rb
class Address < ApplicationRecord
belongs_to :addressable, polymorphic: true
User.rb
class User < ApplicationRecord
has_one :address, :as => :addressable, dependent: :destroy
You cannot directly join the addressable relation as the addressable entities could belong to different models. You could try something like this:
Address
.near([#address.latitude, #address.longitude], 5)
.where(addressable_type: 'User')
.joins("INNER JOIN users on users.id = addresses.addressable_id")
.merge(User.admin)
.pluck(:id)
.merge can be used to invoke scopes of joined tables. Here, User model would have a scope called admin which would return admin users.

Rails 5 check if record exist in belongs_to relations?

I have 3 models Account, Plan and User (And I can not modify the relations model structure, but add scopes or methods)
Account
belongs_to :plan
Plan
belongs_to :user
User
has_may :plans
I want to know if EXISTS an account with a specific user_id
Account.exists?…….. //here is my problem
I would join the database tables by using joins which results in a INNER JOIN in SQL and than add a condition for the user_id in question:
Account.joins(plan: :user).where(users: { id: user_id }).exists?
Read about joins in the Rails Guides.
You can create indirect associations which link Account and User through the Plan model:
class Account < ApplicationRecord
belongs_to :plan
has_one :user, through: :plan
end
class Plan < ApplicationRecord
belongs_to :user
end
class User < ApplicationRecord
has_may :plans
has_many :accounts, through: :plans
end
This will let you query:
Account.joins(:user)
.where(users: { id: user_id })
.exists?
ActiveRecord will automatically handle joining through the plans table.
See the Rails guides:
The has_many :through Association
The has_one :through Association
Specifying Conditions on the Joined Tables

Querying three tables only one table has no association in rails 5

I have three tables in rails
This are the Tables
Employee = (no association at all)
User = has many attendance
Attendance = belongs to user
then my question is how can i query the three table with this.
User table joins Attendance then also joins Employee where employee.code = users.Empkey
how can i translate it to join the three tables in one queries with rails 5
You should create ActiveRecord associations between employees and users.
class Employee < ApplicationRecord
belongs_to :user, foreign_key: "code", class_name: "User"
end
class User < ApplicationRecord
has_many :attendances
has_one :employee, foreign_key: "Empkey", class_name: "Employee"
end
class Attendance < ApplicationRecord
belongs_to :user
end
Now you can play around as you like.
employee = Employee.first
#employee_attendances = employee.user.attendances
You can use raw sql in join table to join 3 tables like see in example
User.joins(:attendances).joins("Inner joins employees on employees.code = users.Empkey")
Hope this will help

Rails sorting result from group(..).sum(..)

I am using rails and graphing some data. I use the following:
<%= column_chart User.includes(:levels).group(:email).sum(:score) %>
How do i make this group command sort the returned array by score from highest to lowest?
My models are arranged as follows
class User < ActiveRecord::Base
has_many :games
contains id, email
end
class Game < ActiveRecord::Base
has_many :levels
belongs_to :user
#contains id, user_id, name
accepts_nested_attributes_for :levels
end
class Level < ActiveRecord::Base
belongs_to :game
#contains id, score and game_id
end
Is your score in Level or in User ?
OK, they're in a deeper nested relation.
You can make your life easier, if your User model declares that:
class User < ActiveRecord::Base
has_many :games
has_many :levels, through: :games
end
Then you have to join the levels.
Looking at the SQL generated by ActiveRecord, you can see that
User.joins(:levels).group(:email).sum(:score)
generates
SELECT sum(score) AS sum_score, email FROM users INNER JOIN games ON games.user_id = users.id INNER JOIN levels ON levels.games_id=games.id GROUP BY email
As sum doesn't return a Relation, but an ActiveSupport::OrderedHash, you cannot append .order() to it.
What you can do, is inject the order before the sum:
User.joins(:levels).group(:email).order('sum_score DESC').sum(:score)
generates
SELECT sum(score) AS sum_score, email FROM users
INNER JOIN games ON games.user_id = users.id
INNER JOIN levels ON levels.games_id=games.id
GROUP BY email
ORDER BY sum_score DESC
which is, what you are looking for.

Ruby on rails querying with join and condition statement

I need to query joining tables without using the primary key(id).
class User < ActiveRecord::Base
has_one :participant
end
class Participant < ActiveRecord::Base
belongs_to :user
end
The User has 'id' and 'name'.
The Participant has 'user_id' which is User.id
I am trying to find the Participant.id by querying with User.name
What I have tried is,
participant_id = Participant.all :joins => :users, :conditions => {:name => "Susie"}
If you're just looking for a specific user's participant id, you could just go:
User.find_by_name("Susie").participant.id
Since your user has a has_one relation to Participant(which belongs to it -- so basically a one-to-one) you can just go call participant on user. ActiveRecord takes care of the join magicks for you
Try the following:
class User < ActiveRecord::Base
has_one :participant
end
class Participant < ActiveRecord::Base
belongs_to :user
scope :foo, lambda {|name|
joins(:users).
where("name = ?", name)
}
end
If you're taking user input you're going to want to probably fix joins so it uses sanitize_sql_array. See here also for some query goodness

Resources