Rails table joins - ruby-on-rails

I'm trying to figure out how to do a table join in one of my models.
There are points, questions, and users.
point.rb
class Point < ActiveRecord::Base
belongs_to :user
belongs_to :question
end
question.rb
class Question < ActiveRecord::Base
has_many :points
end
user.rb
class User < ActiveRecord::Base
In my Points controller I am doing this:
def index
#points = Point.all
#user_points = Point.where('user_id' => current_user)
end
And in my points/index view:
<% #user_points.each do |user_point| %>
<tr>
<td><%= current_user.name %></td>
<td><%= user_point.question_id %></td>
<td><%= user_point.correct_answer %></td>
<td><%= user_point.user_answer %></td>
</tr>
<% end %>
I need to access the name of each question in the questions table (I have the question id available in my view. I'm a n00b to rails, and can't figure out how to this with the documentation.

If you read my previous answer ignore it. I misread your question. This should work.
In your view:
<% user_points.questions.each do |question| %>
...Do whatever...
<% end %>

Take a look at the Rails Guides, especially these two:
http://guides.rubyonrails.org/association_basics.html
http://guides.rubyonrails.org/active_record_querying.html
I think you should be able to set this in your model:
class User < ActiveRecord::Base
has_many :points, :through => :questions
end
in your controller say #user_points = current_user.points
in your view. This should already work with your current code!
<% #user_points.each do |user_point| %>
<td><%= user_point.question.name %></td>
<% end %>

Related

Rails association loop display same primary key in row

I have a loop using associations. I'm looking to group by treatment and display in a row.
Each loop has three records for each treatment. The code below this is what i'm producing.
VIEW
<table>
<tr>
<td>Treatment</td>
<td>Date</td>
<td>Count</td>
</tr>
<% #trial.establishmentMethods.order(:treatment_selection_id).each do |data| %>
<tr>
<td><%= data.treatmentSelection.treatment.name %></td> This is reference by treatment_selection_id.
<td><%= data.date %></td>
<td><%= data.count %></td>
</tr>
<% end %>
</table>
This is what i'm hoping to produce. Display the treatment once, then loop the related treatment_selection_id's on the same row.
Here are my models and associations.
class Trial < ApplicationRecord
has_many :assessments, primary_key: 'trial_id'
has_many :establishmentMethods, through: :assessments
end
class EstablishmentMethod < ApplicationRecord
belongs_to :treatmentSelection, primary_key: 'treatment_selection_id', foreign_key: 'treatment_selection_id'
has_many :treatments, through: :treatmentSelection
end
class TreatmentSelection < ApplicationRecord
belongs_to :treatment, primary_key: 'treatment_id'
end
It seems like TreatmentSelection has_many establishmentMethods, so you should add that to the TreatmentSelection model. Then you can do something like:
<% treatment_selections.each do |treatment_selection| %>
<tr>
<td><%= treatment_selection.treatment.name %></td>
<% treatment_selection.establishmentMethods.each do |em| %>
<td><%= em.date %></td>
<td><%= em.count %></td>
<% end %>
</tr>
<% end %>
By the way, it's convention to use snake_case in ruby and it will make using associations easier.

undefined method operators on legal Postgresql database

I'm beginner, so sorry if i ask for something trivial.
Two tables imed_patient and imed_operator are legal Postgresql tables with relation between them (many patients to one operator by r_opr_code field in imed_patient), described by definitions:
class ImedOperator < ActiveRecord::Base
self.table_name = "imed_operator"
self.primary_key = "code"
belongs_to :ImedPatient
end
class ImedPatient < ActiveRecord::Base
self.table_name = "imed_patient"
self.primary_key = "code"
has_one :ImedOperator, :foreign_key => "r_opr_code"
end
I want to view all patients with data (ex. name, surname) from imed_operator (details of patients), so I produced pacjenci_controller.rb
class PacjenciController < ApplicationController
def index
#patients = ImedPatient.all
#operator = #patients.operators
end
def show
#patient = ImedPatient.find(params[:id])
end
end
In web broweser I receive error :
NoMethodError in PacjenciController#index
undefined method `operators' for #<ImedPatient::ActiveRecord_Relation:0x007fbb269ffe00>
Extracted source (around line #5): #operator = #patient.operators
UPDATE:
my index.html.erb
<h1>Pacjenci w Optimed</h1>
<table>
<tr>
<th>Nazwisko</th>
<th>ImiÄ™</th>
<th>Pesel</th>
<th>Code_operator</th>
<th>Wizyty</th>
<th></th>
<th></th>
</tr>
<% #patients.each do |patient| %>
<tr>
<td><%= link_to #operator.surname, controller: "pacjenci", action: "show", id: patient.r_opr_code %></td>
<td><%= #operator.first_name %></td>
<td><%= #operator.pesel %></td>
<td><%= patient.r_opr_code %></td>
<td><%= link_to 'Wizyty', url_for(action: 'wizytypacjenta', controller: 'wizyty', id: patient.code) %></td>
</tr>
<% end %>
</table>
<br>
<p><%= link_to 'Start', url_for(action: 'index', controller: 'pacjenci') %></p>
<p><%= link_to 'Wstecz', url_for(:back) %></p>
And I stucked :(
ImedPatient has_one ImedOperator, so you need to change
#operator = #patient.operators
to
#operator = #patient.imed_operator
However, I'm not sure you are doing what you want to do. In the index action you are calling ImedPatient.all, so you will get all the records. That's why the variable should be called #patients, not #patient. Then, if you want to get all operators for all the patients, you should use
#operator = #patients.map(&:imed_operator)
If you made a mistake and you actually wanted the #operator in show action it should be:
#operator = #patient.imed_operator
Update: another problem is the has_one declaration. I think it should be:
has_one :imed_operator, :foreign_key => "r_opr_code"
Update 2:
After what you have written in comments it seems that you have confused the association and it should be the other way:
class ImedOperator < ActiveRecord::Base
has_one :imed_patient, foreign_key: 'r_opr_code'
end
class ImedPatient < ActiveRecord::Base
belongs_to :imed_operator , foreign_key: 'r_opr_code'
end
Have a look at: http://guides.rubyonrails.org/association_basics.html#choosing-between-belongs-to-and-has-one

How to save data in database using HABTM in rails 4

I have included
class User < ActiveRecord::Base
has_and_belongs_to_many :subjects
end
class Subjects < ActiveRecord::Base
has_and_belongs_to_many :users
end
I have created one table i.e subjects_users having subject_id and user_id
<% Subject.all.each do |subject| %>
<tr>
<td><%= subject.name %></td>
<td><%= link_to 'Select Subject', final_subject_subject_path(subject) %></td>
</tr>
<% end %>
It goes in controller method:
def final_subject
# now please guide me what I have to write in this so that when select subject is clicked than it will both current_user.id and subject.id in associated table
end
Please help me out in solving this. Thanks in advance
To create subjects for a particular user, you can do it as:
def final_subject
#subject = Subject.find(params[:id)
current_user.subjects << #subject
end

Ruby - ActiveRecord belongs_to and nil association

Imagine the following situation:
I have a user model and a user_group model, so:
Class User < ActiveRecord::Base
belongs_to :user_group
end
Class UserGroup < ActiveRecord::Base
has_many :users
end
Now, let say some of the user does not have group. Which mean, when I call:
<% #u.each do |item| %>
<tr>
<td><%= item.id %></td>
<td><%= item.username %></td>
<td><%= item.name %></td>
<td><%= item.user_group.name %></td>
</tr>
<% end %>
It will throw nil. Is there any way nil will be displayed as empty string (somewhat like LEFT JOIN, or DataMapper include_related in CodeIgniter) instead of showing error page?
Right now I am using
<%= item.user_group.name unless item.user_group.nil? %>
to check before calling, but doing that for all view file is somewhat not a good approach.
Thanks in advance!
use try..
class Manufacturer < ActiveRecord::Base
has_many :products
def contact
"Manufacturer has been contacted."
end
end
Product.first.try(:manufacturer).try(:contact)
#=> nil
Product.last.try(:manufacturer).try(:contact)
#=> "Manufacturer has been contacted."
You can use an helper too:
def group_name_for(item)
item.user_group.name unless item.user_group.nil?
end
And call that helper in your views:
<%= group_name_for(item) %>

Need data from a many:many join in a Rails view

Its maybe not the best solution in most cases, but i want a table with data form 3 tables.
class Media < ActiveRecord::Base
belongs_to :user
belongs_to :type
has_many :ratings
end
class User < ActiveRecord::Base
has_many :medias
has_many :ratings
end
class Rating < ActiveRecord::Base
belongs_to :user
belongs_to :media
end
Thats the view I want
<table>
<tr>
<th>Name</th>
<th>Comment</th>
<th>Creator</th>
<th>Type</th>
<% for user in #users %>
<th><%=h user.login %></th>
<% end %>
</tr>
<% for media in #medias %>
<tr>
<td><%=h media.name %></td>
<td><%=h media.comment %></td>
<td><%=h media.user.login %></td>
<td><%=h media.type.name %></td>
<% for user in #users %>
<td><%=h GET_RATING (media, user) %></td>
<% end %>%>
</tr>
<% end %>
</table>
Basicly i want one new row for each users ratings for each media
What I want is a Table that looks like that:
media.name media.comment ... rating(media, user).rating
I think it would be better to use a join in the Controller with the Media find methods but I dont know how exactly, enougher possible solution could be helper method that takes media and user as parameters.
What do you think is the best solution for this?
This kind of association belongs in your model, a has many through relationship is perfect for this.
class User < ActiveRecord::Base
has_many :ratings
has_many :media, :through => :ratings
end
class Media < ActiveRecord::Base
has_many :ratings
has_many :users, :through => ratings
end
class Rating < ActiveRecord::Base
belongs_to :user
belongs_to :media
end
Then you can access
media.name media.comment
Then could also access
user.ratings
or:
<% media.users.each do |user| %>
## Do stuff with user.ratings array
<% end %>
You can also:
media.ratings.each do |rating|
rating.your_attribute
rating.user.your_attribute
end

Resources