iterating data from 2 models - ruby-on-rails

In my index I'm trying to iterate through records through records in 2 models, job and employer. I've set up a has_many relationship.
Rails its throwing a undefined method `each' for #
job model
attr_accessible :title, :location
belongs_to :employer
employer model
attr_accessible :companyname
has_many :jobs
job controller
def index
#jobs = Job.find(:all, :include => :employer)
index
<% #jobs.each do |job| %>
<%= job.title %>
<%= job.location %>
<% job.employer.each do |employer| %>
<% employer.companyname %>
<% end %>
<% end %>

That's because a job has one employer, not many. That's what the belongs_to means. See this Rails guide about setting up actual many-to-many relationships.
But I think in your case you do want it to be a one-to-many. Why would a job have multiple employers? Instead, just output the single employer company name.
More Info
You still want a belongs_to on your Job model. belongs_to go on models that have a foreign key referencing some other model. In this case, your Job model has an ID pointing at an Employer (it has an employer_id field). That has_one or has_many associations are for when no foreign key exists on the model but a relationship still exists.
So your Job model has a method called employer (singular) but not employers (plural) because it belongs to a single employer. An employer has many jobs under them, so the has_many association gives you a jobs (plural) method, not a job (singular) method.
The link I posted for the Rails guide does an excellent job of showing more of this, with more details and explanation, and more examples.
Addtional Code Bit
With the above, you will want to change your code to be like this:
<% #jobs.each do |job| %>
<%= job.title %>
<%= job.location %>
<%= job.employer.companyname %>
<% end %>
Notice how you can go straight to accessing the attributes on the employer that you want. And that will do it!

Have you tried running this in the rails console?
Job.last.employer
If that doesn't work your relationship isn't set up properly.
Does your Job model have an employer_id field? Did you run rake db:migrate to make sure all your migrations are run?

Related

Rails table with a where clause

I have an employee NonAvailability model and instead of displaying all the non availabilities in the table with
<% #non_availabilities = NonAvailability.all %>
<% #non_availabilities.each do |non_availability| %>
<%= non_availability.employee.full_name %>
<%= non_availability.date %>
<%= non_availability.time %>
<%= non_availability.reason %>
I want to only display the nonavailabilities that correlate to a certain employees id.
How can I do this?
There are multiple ways to retrieve records in rails. For example you can filter NonAvailability with employee_ids using where method
ids = [1,2,3,4] # ids of employee
NonAvailabilty.where(employee_id: ids)
If you want to utilize method chaining, define a has_many and belongs_to association in your Employee and NonAvailability model. Assuming that your design have this specifications.
# employee.rb
class Employee
has_many :non_availabilities
end
# non_availability.rb
class NonAvailability
belongs_to :employee
end
Then you can retrieve all non_availabilites using employee object.
employee = Employee.find_by(id: 1)
employee.non_availabilities
For more info visit this Active Record Association Guide

Fetch id of selected option in dropdown in controller

I have a model named 'Assessment':
class Assessment < ApplicationRecord
has_many :assessment_students
has_many :students, through: :assessment_students
end
Join table is:
class AssessmentStudent < ApplicationRecord
belongs_to :student
belongs_to :assessment
end
There is another model:
class Classroom < ApplicationRecord
has_many :classroom_students
has_many :students, through: :classroom_students
has_many :assessments
end
In show,html.erb of classrooms, I have a dropdown which shows all assessments (generated from assessment table).
Code is:
<%= collection_select(:assessment :assessment_id, Assessment.all, :id, :assessment_name , :prompt => true) %>
Requirement of the project is: Based on the assessment chosen by the user in the show.html.erb page, we have to show all students details like name etc assigned to that particular assessment. I have stored this data in join table 'AssessmentStudent '. However, I am not sure how to pass id from the above collection_select to classroom controller. I have below code:
show.html.erb:
<%= collection_select(:assessment :assessment_id, Assessment.all, :id, :assessment_name , :prompt => true) %>
<div id="divResult">
<% #assessmentstudents1.each do |t| %>
<% t.assessment_students.each do |record| %>
<%= record.student_id %>
<% end %>
<% end %>
</div>
classroom controller:
def show
#assessmentstudents1 = Assessment.find(params[:assessment][:assessment_id]).preload(:assessment_students)
end
def classroom_params
params.require(:classroom).permit(:classroom_name, :classroom_year, :customer_id, :classroom_student, :student_ids => [])
params.require(:assessment).permit(:assessment_id)
end
I would first recommend to make a change to the controller structure of your application. Because the responsibility of the show action of your ClassroomsController should be to display the details of the classroom. When you want to show the details of an Assessment, that should be handled by an AssessmentsController.
First of all, I'm gonna assume that your Assessment model has a belongs_to :classroom association. Then I would suggest creating the following structure.
config/routes.rb
resources :classrooms
resources :assessments
app/views/classrooms/show.html.erb
<% #classroom.assessments.each do |assessment| %>
<%= link_to assessment_name, assessment_path(assessment) %>
<% end %>
app/controllers/assessments_controller.rb
class AssessmentsController < ApplicationController
def show
#assessment = Assessment.find(:id)
end
end
app/views/assessments/show.html.erb
<h1>Students for <%= #assessment.assessment_name %></h1>
<% #assessment.students.each do |student| %>
<p><%= student.student_name %></p>
<% end %>
<h2>In classroom:</h2>
<p><%= #assessment.classroom.classroom_name %></p>
So to explain what is happening here, we have configured the routes to allow the server to respond to the url /assessments/:id which will lead to the AssessmentsController#show action being called.
That action is being called when the user clicks on any of the links that we have setup in the classrooms/show template. Note that I used individual links for now instead of a select dropdown, because it is easier to setup and understand how it works. And like the previous answer suggested, using a select tag requires a little bit of JavaScript to get working.
And lastly, when the assessments/show template is being rendered, it will list out all of the students related to that particular assignment. And I also included which classroom it is assigned to (if my assumption of belongs_to was correct).
On a side note, if your question tag of ruby-on-rails-3 is correct, then the usage of params.permit and params.require is invalid, because that is something that was introduced in Rails 4 (unless I'm mistaken). And in any case, you only have to use permit when database updates take place, which means the create and update actions, not index, show, etc, because it is a way of restricting which changes are allowed.
Tag select does nothing by itself. So there are two possible options.
The first is wrapping select in form tag then submitting the form will lead to request. The second is writing a handler using JavaScript which will listen to select changes.

rails relationship. Rails 4

I'm new in the world of rails developers. Please, help me to understand.
I've 3 tables:
Calls, Questions, Results
Calls is:
id, name, date
Questions is:
id, question
Results is:
id, call_id, question_id, result
I've read the Rails manual, as i understand i've created 3 models.
In my model Call.rb
I've done next relationship:
has_many :results
has_many :question, through: :results
My Result.rb
belongs_to :call
belongs_to :question
My Question.rb
has_many :result
So, there are can be many records in the table "results" with one call_id, and it's can be one relation with question through results table
If if try to launch code like this:
#calls = Call.all
Than on my view:
<% #calls.each do |call| %>
<%= call.result.result %>
<% end %>
i've error that "result is undefined method". But it's must be a property.
What i do wrong?
Thanks!
According to your schema, your associations should look like this
class Call < ActiveRecord::Base
has_many :questions
has_many :results
end
class Question < ActiveRecord::Base
belongs_to :call
end
class Result < ActiveRecord::Base
belongs_to :call
end
So in the view,
<% #calls.each do |call| %>
<% call.results.each do |result| %>
<%= result.result%>
<% end %>
<% end %>
A few things.
First, you need to fix your associations so the plural and singular tenses match. has_many :result does not work as Marcelo points out.
Second, you need to ensure that your tables actually have the correct id's to make the associations work. Use the rails console to inspect Result. From your question info, it should have attributes for call_id and question_id. Once you've confirmed this, create a few objects in the console and test your associations.
#call = Call.create(name: "test", date: Time.now)
#result = Result.create(call_id: #call.id, result: "some result")
Then
#call.result # should yield the Result record you just created
Lastly, you need to rename the result attribute for Result. That's super confusing and will only cause problems.
The first thing I notice is that your call should have many questions, and many results through questions. That's because calls own questions, which in turn own results themselves.
class Call < ActiveRecord::Base
has_many :questions
has_many :results, through: :questions
end
You didn't need call_id in Result class. But, if you wish to keep it there, you dont need through: :questions in your call class (given there is a direct relation between them)
In your Question class, I assume it is a typo, but it should be plural
has_many :results
Having said that, your loop through calls will bring results (plural) and not result (singular) given that a call may have many results. Therefore:
<% #calls.each do |call| %>
<% call.results.each do |result| %>
<%= call.result %>
<% end %>
<% end %>

Find items with belongs_to associations in Rails?

I have a model called Kase each "Case" is assigned to a contact person via the following code:
class Kase < ActiveRecord::Base
validates_presence_of :jobno
has_many :notes, :order => "created_at DESC"
belongs_to :company # foreign key: company_id
belongs_to :person # foreign key in join table
belongs_to :surveyor,
:class_name => "Company",
:foreign_key => "appointedsurveyor_id"
belongs_to :surveyorperson,
:class_name => "Person",
:foreign_key => "surveyorperson_id"
I was wondering if it is possible to list on the contacts page all of the kases that that person is associated with.
I assume I need to use the find command within the Person model? Maybe something like the following?
def index
#kases = Person.Kase.find(:person_id)
or am I completely misunderstanding everything again?
Thanks,
Danny
EDIT:
If I use:
#kases= #person.kases
I can successfully do the following:
<% if #person.kases.empty? %>
No Cases Found
<% end %>
<% if #person.kases %>
This person has a case assigned to them
<% end %>
but how do I output the "jobref" field from the kase table for each record found?
Maybe following will work:
#person.kase.conditions({:person_id => some_id})
where some_id is an integer value.
Edit
you have association so you can use directly as follows:
#kases= #person.kases
in your show.rhtml you can use instance variable directly in your .rhtml
also #kases is an array so you have to iterate over it.
<% if #kases.blank? %>
No Kase found.
<% else %>
<% for kase in #kases %>
<%=h kase.jobref %>
<% end %>
<% end %>
If your person model has the association has_many :kases then, you can get all the cases that belongs to a person using this
#kases = Person.find(person_id).kases
Assuming person_id has the id of the person that you want to see the cases for.
You would probably want something like
has_many :kases
in your Person model, which lets you do #kases = Person.find(person_id).kases
as well as everything else that has_many enables.
An alternate method would be to go through Kase directly:
#kases = Kase.find_all_by_person_id(person_id)

Rails link from one model to another based on db field?

I have a company model and a person model with the following relationships:
class Company < ActiveRecord::Base
has_many :kases
has_many :people
def to_s; companyname; end
end
class Person < ActiveRecord::Base
has_many :kases # foreign key in join table
belongs_to :company
end
In the create action for the person, I have a select box with a list of the companies, which assigns a company_id to that person's record:
<%= f.select :company_id, Company.all.collect {|m| [m.companyname, m.id]} %>
In the show view for the person I can list the company name as follows:
<%=h #person.company.companyname %>
What I am trying to work out, is how do I make that a link to the company record?
I have tried:
<%= link_to #person.company.companyname %>
but that just outputs the company name inside a href tag but links to the current page.
Thanks,
Danny
You need pass in second argument the path where you want go
<%= link_to #person.company.companyname, #person.company %>
or with the full version :
<%= link_to #person.company.companyname, company_url(#person.company) %>
The thing is, link_to cannot guess where you want it to lead to, if you give it only the text of the link :)
In order to have the link lead to the company page, you need to add a path:
<%= link_to #person.company.companyname, company_path(#person.company) %>
This assumes you have proper restful routes for your company
map.resources :companies
and the page you're heading to is companies/show.html.erb.

Resources