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
Related
I have these models
class Auto < ApplicationRecord
belongs_to :marca
belongs_to :modelo
belongs_to :cliente
end
class Cliente < ApplicationRecord
has_many :autos
end
class Marca < ApplicationRecord
has_many :modelos
has_many :autos
end
class Modelo < ApplicationRecord
belongs_to :marca
has_many :autos
end
and this index view
<table class="table table-striped" id="autos">
<tr>
<th>Id</th>
<th>Cliente</th>
<th>Marca</th>
<th>Modelo</th>
<th>Placas</th>
</tr>
<% #auto.each do |auto| %>
<tr>
<td><%= auto.id %></td>
<td><%= auto.cliente.nombre %></td>
<td><%= auto.marca.nombre%></td>
<td><%= auto.modelo.nombre %></td>
<td><%= auto.placas %></td>
</tr>
<% end %>
</table>
and this in my autos controller
def show
#auto = Auto.find(params[:id])
end
def index
#auto = Auto.all
end
the problem is that show me this error:
undefined method `nombre' for nil:NilClass in this line:
<td><%= auto.cliente.nombre %></td>
rarely at show view where I call
#auto.cliente.nombre
works fine, can you help me? thanks
It seems like <td><%= auto.cliente.nombre %></td> doesn't work because auto.cliente is nil, and you cannot call that method nombre on nil. Perhaps one of your auto objects doesn't have an associated client?
To see how this happens, try running nil.hello in Ruby and you should see a NoMethodError with the error message undefined method 'hello' for nil:NilClass.
auto.cliente.try(:nombre) will save you from error if you by chance allow auto without cliente.
I am creating a trivia game where there are multiple categories (like sports, history, art, etc.). At the end of each category's game, I want to show a scoreboard of results only for that single category.
By specifying the category in the method, I am now successfully filtering only for history scores, as seen here:
class ScoreboardController < ApplicationController
def index
#participations = Participation.where(finished: true, category: "history").order(score: :desc)
end
end
While that is good, I now need to make it so that the scoreboard controller can produce a filtered set of scores for history, sports, and any other number of category iterations, whereas it only covers the history category at current.
To make this happen, I tried creating a second method within the controller for:
#participations = Participation.where(finished: true, category: "sports").order(score: :desk)
Unfortunately, that still only returned scores from the first method for history with no sports scores.
I think I am doing one of two things wrong:
1) Am I writing the methods incorrectly by adding additional iterations into the same controller?
2) In the scoreboard view (as opposed to the scoreboard controller), I am not calling the controller correctly.
Any ideas where I am going wrong?
Additional Info: Scoreboard View
<thead>
<tr>
<th>#</th>
<th>User</th>
<th>Category</th>
<th>Score</th>
</tr>
</thead>
<tbody>
<% #participations.each_with_index do |participation, index| %>
<tr>
<td>#<%= index + 1 %></td>
<td><%= participation.user.username %></td>
<td><%= participation.category %></td>
<td><%= participation.score %></td>
</tr>
<% end %>
</tbody>
You should change your ScoreboardController index to contain different instance variables for different categories. ie:
ScoreboardController.rb
def index
#participations_score = Participation.where(finished: true, category: "history").order(score: :desc)
#participations_history = Participation.where(finished: true, category: "sports").order(score: :desc)
# other particpation categories
end
index.html.erb
<h1>History Scoreboard</h1>
<thead>
<tr>
<th>#</th>
<th>User</th>
<th>Category</th>
<th>Score</th>
</tr>
</thead>
<tbody>
<% #participations_history.each do |participation_history| %>
<tr>
<td>#<%= participation_history.id %></td>
<td><%= participation_history.username %></td>
<td><%= participation_history.category %></td>
<td><%= participation_history.score %></td>
</tr>
<% end %>
</tbody>
<!--- Add more code for the rest of the categories --->
I strongly suggest that you brush up on your knowledge of the Ruby programming language as well as the Ruby on Rails framework. You can do so by going to Code academy.
Sounds like a job for nested resources, with a singular resource for:
#config/routes.rb
resources :categories do
resource :scoreboard, module: :categories #-> url.com/categories/:category_id/scoreboard
end
#app/controllers/categories/scoreboards_controller.rb
class Categories::ScoreboardsController < ApplicationController
def show
#results = Participation.where(finished: true, category: params[;category_id]).order(score: :desc)
end
end
This will allow you to invoke the scoreboards#show action, populating with the appropriate category from the routes....
#app/controllers/categories_controller.rb
class CategoriesController < ApplicationController
def create
#category = ...
redirect_to [#category, :scoreboard]
end
end
Associations
Now, there's a better way.
Instead of calling Participation naked, you'll be best using the categories and scoreboards association you should have set up in the backend:
#app/models/category.rb
class Category < ActiveRecord::Base
has_many :participations
has_many :scoreboards, through: :participations
end
#app/models/participation.rb
class Participation < ActiveRecord::Base
belongs_to :category
belongs_to :scoreboard
end
#app/models/scoreboard.rb
class Category < ActiveRecord::Base
has_many :participations
has_many :categories, through: :participations
end
This will allow you to use the same routes as above, but this time populating the response through the associations:
#app/controllers/categories/scoreboards_controller.rb
class Categories::ScoreboardsController < ApplicationController
def show
#category = Category.find params[:id]
#results = #category.participations.where(participation: {attribute: true})
end
end
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) %>
I have two controllers: tasks, tasksperson.
I have views/tasks/index.html.erb:
<table>
<% #tasks.group_by(&:name).each do |name, tasks| %>
<tr>
<td><%= name %></td>
<td><%= tasks.size %></td>
<td><%= tasks.select{ |task| task.done != true }.size %></td>
</tr>
<% end %>
</table>
I want to create a link in views/tasks/index.html to views/tasksperson/index.html.erb.I want also to send the name into 'index' in Tasksperson_controller.. I tried to do this by getting params[:name] but I think it's wrong
maybe, I need to do something like:
<td><%= link_to 'Show Tasks', tasksperson_path(name) %></td>
this is my tasksperson_controller:
class TaskspersonController < ApplicationController
def index
#tasks = Task.where(:name => params[:name]) respond_to do |format|
format.html # index.html.erb
format.json { render json: #tasks }
end
end
end
and views/tasksperson/index.html.erb:
<table>
<tr>
<th>Name</th>
<th>num of tasks</th>
<th>num tasks left</th>
<th>test</th>
</tr>
<% #tasks.each do |f| %>
<tr>
<td><%= f.name %></td>
<td><%= f.task %></td>
<td><%= f.done %></td>
</tr>
<% end %>
</table>
You need to add :name as a parameter to the rule that defines the route to TaskspersonController#index in routes.rb
so it would be something like this:
match 'tasksperson/index/:name' => 'tasksperson#index', as: :tasksperson_path
Based on your comment "...so Task have many taskpersons" I think you want a data model similar to below
class Task < ActiveRecord::Base
has_many :assigned_tasks
has_many :people, :through => :assigned_tasks
end
# maybe this is just the User class?
class Person < ActiveRecord::Base
has_many :assigned_tasks
has_many :tasks, :through => :assigned_tasks
end
# was TaskPerson
class AssignedTask < ActiveRecord::Base
belongs_to :task
belongs_to :person
end
See http://guides.rubyonrails.org/association_basics.html#the-has_many-through-association for information about "The has_many :through Association"
task = Task.create(:title => "Go up the hill")
jack = Person.find(00000)
jill = Person.find(00000)
task.people << jack
task.people << jill
task.assigned_tasks.each do |join|
puts join.created_at
puts join.person.name
# 0 - jack
# 1 - jill
end
task.people.each do |person|
puts person.name
end
I am not exactly sure what you are trying to display in your views, it looks like you are grouping by a task name attribute in task/index, is that the Persons name?
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 %>