One-to-one association - ruby-on-rails

I have two models and I want to display them in one table.
Model 1:
class Name < ActiveRecord::Base
has_one :employer, :foreign_key => 'application_id'
end
Model 2:
class Employer < ActiveRecord::Base
belongs_to :name, :foreign_key => 'application_id'
end
Controller:
def summary
#name = Name.all
end
I have this in my view:
<% #name.each do |e| %>
<tr>
<td ><%= e.application_id %></td>
<td ><%= e.Name_of_employee%></td>
<td ><%= e.Employer_name%></td>
</tr>
<% end %>
The name only have one employer.
I am getting "undefined method `Employer' for #
"
TYIA!

as the association is defined,
has_one :employer, :foreign_key => 'application-id'
notice the case employer, so it has to be small case, and not class name
<td ><%= e.employer.name %></td> # name or some other attribute you wish to display
Also, including the association first will help eliminate n+1
#name = Name.includes(:employer)

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.

How to use has_many fields in views, rails?

Frnds I am new to rails, here i created two tables caleed stocks and stock_availabilities.
in the stock model
class Stock < ActiveRecord::Base
belongs_to :projects_lkp
has_many :stock_availabilities
validates_presence_of :item
end
In the stock_availabilities model
class StockAvailability < ActiveRecord::Base
belongs_to :stock
validates_presence_of :qty,:add_or_issue,:price, :captured_at, :stock_id,:unit
end
Now my doubt is how to bring the field of stock_availabilties in the views of stock
<% #stock.each do |d| %>
<tr>
<td><%= d.item %></td>
"Here i need to print the values of qty and pricevwhich is in stock_availabilities class"?
</tr>
You are on the right track.
this is what you need:
<% #stock.each do |d| %>
<tr>
<td><%= d.item %></td>
<% d.stock_availabilities.each do |sAV| %>
<td> <%= sAV.qty %> </td>
... <-- You do the other ones here
<% end %>
</tr>

Struggling to get two models to have relations. And who suffers? The views

I've got an app that sets timed challenges for users. Each user is associated with one or more challenges. I've setup the models so they connect via a join table. That works fine, but I'm having problems on my view level. In the index view for the challenges, data from the challenge model and from the user model are displayed. But where the view should display the user's name, it's just displaying "User." If you click on "User", you are taken to the correct "show" page for that user. So the link works fine, but I can't get the user's name to appear. Instead, I'm just getting the class name to appear. Any idea why?
Here's the code for the view. The file directly below is is views/challenges/index.html.erb
<%- model_class = Challenge.new.class -%>
<h1><%=t '.title', :default => model_class.model_name.human.pluralize %></h1>
<table class="table table-striped">
<thead>
<tr>
<th><%= model_class.human_attribute_name(:date) %></th>
<th><%= model_class.human_attribute_name(:time) %></th>
<th><%= model_class.human_attribute_name(:rider) %></th>
<th><%=t '.actions', :default => t("helpers.actions") %></th>
</tr>
</thead>
<tbody>
<% #challenges.each do |challenge| %>
<tr>
<td><%= link_to challenge.date, challenge_path(challenge) %></td>
<td><%= link_to challenge.duration, challenge_path(challenge) %></td>
<td><%= link_to challenge.users.name, user_path(challenge) %></td>
</tr>
<% end %>
</tbody>
</table>
And here's the relevant models.
Challenge.rb
class Challenge < ActiveRecord::Base
attr_accessible :date, :duration, :user
has_many :user_challenges
has_many :users, :through => :user_challenges
validates_presence_of :date, :duration
def self.winner
Challenge.find(:first, :order => "duration desc")
end
end
User.rb
class User < ActiveRecord::Base
attr_accessible :name, :email
has_many :user_challenges
has_many :challenges, :through => :user_challenges
validates_presence_of :name, :email
validates_uniqueness_of :email
def self.find_or_create(name, email)
user = User.find_by_email(email)
if user.present?
user.challenge = challenge
user.save
else
User.create(:name => name, :email => email)
end
end
end
Join table, aka User_challenge.rb
class UserChallenge < ActiveRecord::Base
belongs_to :challenge
belongs_to :user
end
challenge.users is a collection and .name is a ruby method that gives you the name of the class:
ruby-1.9.2-head :002 > Object.name
=> "Object"
Call the attribute something else (username).
Also, user_path(challenge) doesn't really make sense when a Challenge can have_many :users (which users path should it be?).
I think the users list is empty, and that's why users.first.username is nil.
the user_path(challenge) 'seems' like its working, but its probably always taking you to the users/challenge_id path, which is not what you want.
most likely something isn't saving correctly for you. verify that your users lists are not empty. hop in the console and test out the saving and reloading of your data

form_for for relation table with type of many to many relation

My goal is to display select box for each relation for users and specific project.
All users need to be listed but only project users have some type of relation. Other users have none selected in theirs select box.
I have this model:
class Project < ActiveRecord::Base
belongs_to :company
has_many :tasks, :order => 'state_type_id ASC'
has_many :project_user_relations
has_many :users, :through => :project_user_relations
def t_name
name.camelcase
end
end
class User < ActiveRecord::Base
belongs_to :company
has_many :tasks , :foreign_key => :assigned_user_id
has_many :project_user_relations
has_many :projects, :through => :project_user_relations
def full_name
firstname + ' ' + lastname
end
def relation_to(project)
relation=ProjectUserRelation.find_by_project_id_and_user_id(project.id, id)
relation ||= relation=ProjectUserRelation.new
end
end
class ProjectUserRelation < ActiveRecord::Base
belongs_to :project
belongs_to :user
has_one :project_user_relation_type
end
class ProjectUserRelationType < ActiveRecord::Base
def t_name
I18n.t("app.projects.users.relation.type."+code)
end
end
I want make a form to display all users, with collection_select.
I used code:
def edit_all
#project = Project.find(params[:project_id])
#users = User.all
....
in my controler
routes works ok.
in my view:
<% #users.each do |user| %>
<%= f.fields_for :users, user do |user_fields| %>
<tr class="reference" rel="<%= parent_user_path(user) %>" >
<td class="name"><%= link_to user.full_name, parent_user_path(user) %></td>
<td class="email"><%= mail_to user.email %></td>
<td class="type">
<%= user_fields.fields_for user.relation_to #project do |relation_fields| %>
<%= relation_fields.collection_select :project_user_relation_type, ProjectUserRelationType.all, :id, :t_name, {:include_blank => false, :prompt => t("helpers.select.prompt") } %>
<% end %>
</td>
</tr>
<% end %>
<% end %>
or for test:
<%= f.fields_for :users, #users do |xuser_fields| %>
<% logger.debug "#{self.to_s} xuser_fields = #{xuser_fields.object.inspect} ;" %>
<tr>
<td><%= xuser_fields.text_field :firstname %></td>
<td></td>
<td></td>
<td></td>
</tr>
<% end %>
but notnihng woks right
first one generates wrong name in html:
select id="project_users_project_user_relation_project_user_relation_type" name="project[users][project_user_relation][project_user_relation_type]"
second one generates error:
undefined method `firstname' for # Array:0x4d03658
Can you help me to solve this situation.
PS:sorry for long code :(
SOLUTION (probably - solved by reading RoR sources)
I found sollution i thing.
A method
def name_attributes=(attributes)
# Process the attributes hash
end
in Project model was missing.
It is unbelievable sollution :].
There is also exact syntax after fields_for: :name, #some_collection, where name must be exactly same name as in the beginign of mentioned def in Model.

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