Rails 3 with joins among 2 tables - mysql

I have 2 models, car and registrations.
class Car < ActiveRecord::Base
belongs_to :Registration
end
class Registration < ActiveRecord::Base
has_many :cars, :dependent => :destroy
accepts_nested_attributes_for :cars, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
end
In CarsController:
def index
#cars = Car.all
#cars2 = Car.all(:joins => :Registration)
end
In view:
<% #cars.each do |car| %>
<tr>
<td><%= car.twitter %></td>
<td><%= car.facebook %></td>
<td>
<% #cars2.Registration.each do |h| %> #here is my problem
<%= h.email %>
<% end %>
</td>
</tr>
<% end %>
This is my statement of cars. I am trying to print for every car owner's email. The email is in table Registration (model registration). I don't know how to make a query to database, that I want to get email from table Registrations, when column registration_id in table Cars == id column of table Registrations...
So I would like to ask you, if you have a tip, how to do...

You have got your associations in capital letters. It should be in small like this
class Car < ActiveRecord::Base
belongs_to :registration
end
Also you dont have to assign 2 variables in the controller
def index
#cars = Car.includes(:registration)
end
and in the view
<% #cars.each do |car| %>
<tr>
<td><%= car.twitter %></td>
<td><%= car.facebook %></td>
<td>
<%= car.registration.email %> #here is my problem
</td>
</tr>
<% end %>

Use this instead to fetch the email:
<%= car.registration.email %>
If you want eager loading, then use the following line in your controller instead:
#cars = Car.includes(:registration)
There's no need for #cars2.

Related

Ruby on rails: How to display information from another table?

Updated: 22/08/2019
This is working now. Thanks for feedback and help!
Image of Benefit list: List Display <-- Needed to params permit benefit_ids
Old Version: 21/08/2019
I have set up many to many associations but can't get the data table name. I can get the ID but it won't allow me to display the other fields information.
I have looked in the controller and added to permit benefit_ids but not sure if I should add anything else to it.
exercisetypes(Index.html.erb)
--- Old code (21/08/2019)
<tbody>
<% #exercisetypes.each do |exercisetype| %>
<tr>
<td><%= exercisetype.name %> </td>
<td><%= exercisetype.benefits.name %> </td>
...
---
New code (22/08/2019)
<tbody>
<% #exercisetypes.each do |exercisetype| %>
<tr>
<td> <%= exercisetype.name %> </td>
<td>
<ul>
<% exercisetype.benefits.each do |benefit| %>
<li><%= benefit.name %></li>
<% end %>
</ul>
</td>
<% end %>
...
_form.html.erb(Gem: simple form)
<% f.association :benefits, as: :check_boxes %>
Models
exercisetype.rb
has_many :exercisetype_benefits, dependent: :destroy
has_many :benefits, :through => :exercisetype_benefits
benefit.rb
has_many :exercisetype_benefits
has_many :exercisetypes, :through => :exercisetype_benefits
exercisetype_benefit.rb
belongs_to :exercisetype
belongs_to :benefit
The table displays the model name Benefit. There are no error messages but I am not sure how to display the name of the benefit.
exercisetype.benefits is a collection:
# index.html.erb
<ul>
<% exercisetype.benefits.each do |benefit| %>
<li><%= benefit.name %></li>
<% end %>
</ul>
Benefits belongs to exercisetype model, so you need to iterate over benefits to access the attributes. Check this:
<tbody>
<% #exercisetypes.each do |exercisetype| %>
<tr>
<td><%= exercisetype.name %> </td>
<td>
<ul>
<% exercisetype.benefits.each do |benefit| %>
<li><%= benefit.name %></li>
<% end %>
</ul>
</td>
</tr>
<% end %>
</table>
Exercise has_many benefits which mean when you do exercise.benefits it will return a collection of benefits object so you need to iterate through it.
Your collection will look like
`#<ActiveRecord::Associations::CollectionProxy [#<Benefit id: 1, name: "Good Health">, #<Benefit id: 2, name: "Blood flow">]>`
So you need to iterate through it like.
<% exercisetype.benefits.each do |benefit| %>
<li><%= benefit.name %></li>
<% end %>

update join table has_many through with additional checkboxes

if i dont find solution here i have no idea where i should looking for...
I know there is right, easy solution for it...but something i just dont understand.
I have 3 models...
Scheme.rb
class Scheme < ActiveRecord::Base
has_many :projects
has_many :custom_issue_field_definitions, through: :scheme_custom_issue_field_definitions
has_many :scheme_custom_issue_field_definitions
end
CustomIssueFieldDefinition.rb
class CustomIssueFieldDefinition < ActiveRecord::Base
has_many :schemes, through: :scheme_custom_issue_field_definitions
has_many :scheme_custom_issue_field_definitions
belongs_to :custom_issue_field
end
SchemeCustomIssueFieldDefinition.rb
class SchemeCustomIssueFieldDefinition < ActiveRecord::Base
belongs_to :scheme
belongs_to :custom_issue_field_definition
end
Join Model have 3 additional fields...with type: boolean.
I'd like to update scheme_custom_issue_field_definitions table. How controller and form should looks like?
Additional image:
Update:
In console i can update it like this:
a = Scheme.first
b = CustomIssueFieldDefinition.first
c = a.scheme_custom_issue_field_defintitions.find_or_create_by(custom_issue_field_definition: b)
c.update_attributes(visible: 1, reportable: 0, required: 0)
Next Update:
Now form looks like this (what is completely wrong):
<%= simple_form_for #scheme_new_custom_issue_field, url: configurations_scheme_path(#scheme), method: :put do |f| %>
<% #available_custom_issue_field_definitions.each do |custom_issue_field| %>
<tr>
<td><%= custom_issue_field.label %></td>
<td><%= f.input :visible, as: :boolean %></td>
<td><%= f.input :reportable, as: :boolean %></td>
<td><%= f.input :required, as: :boolean %></td>
</tr>
<% end %>
<%= f.button :submit, class: "btn btn-primary" %>
<% end %>
and schemes_controller
def update
#scheme = Scheme.find(params[:id])
#scheme_new_custom_issue_field = #scheme.scheme_custom_issue_field_definitions.
find_or_create_by(scheme_id: #scheme, custom_issue_field_definition_id: params[:custom_issue_field_definition_id])
if #scheme_new_custom_issue_field.update_attributes(scheme_custom_issue_field_definition_params)
flash[:success] = "Scheme has been successfully updated"
redirect_to :back
else
render :edit
end
end
Update Solution:
If you want to create new SchemCustomIssueFieldDefinition record in the console, I suggest this alternative:
a = Scheme.first
b = CustomIssueFieldDefinition.first
c = SchemeCustomIssueFieldDefinition.find_or_initialize_by(scheme: a, custom_issue_field_definition: b)
c.assign_attributes(visible: 1, reportable: 0, required: 0)
c.save
This will save you one less query than your current example code as this will not do have an UPDATE sql.
For your form:
<%= simple_form_for #scheme, method: :patch do |f| %>
<% #available_custom_issue_field_definitions.each do |custom_issue_field| %>
<tr>
<%= f.simple_fields_for :scheme_custom_issue_field_definitions, #scheme.scheme_custom_issue_field_definitions.find_or_initialize_by(custom_issue_field_definition: custom_issue_field) do |ff| %>
<%= ff.hidden_field :id %>
<%= ff.hidden_field :scheme_id, value: #scheme.id %>
<%= ff.hidden_field :custom_issue_field_definition_id, value: custom_issue_field.id %>
<td><%= custom_issue_field.label %></td>
<td><%= ff.input :visible, as: :boolean %></td>
<td><%= ff.input :reportable, as: :boolean %></td>
<td><%= ff.input :required, as: :boolean %></td>
<% end %>
</tr>
<% end %>
<%= f.button :submit, class: "btn btn-primary" %>
<% end %>
schemes_controller.rb:
class SchemesController < ApplicationController
# ...
def update
#scheme = Scheme.find(params[:id])
if #scheme.update(scheme_params)
flash[:success] = "Scheme has been successfully updated"
redirect_to :back
else
render :edit
end
end
# ...
private
def scheme_params
# update below if you need other scheme attributes to be updated
params.require(:scheme).permit(:id, scheme_custom_issue_field_definitions_attributes: [:id, :scheme_id, :custom_issue_field_definition_id, :visible, :reportable, :required])
end
end
scheme.rb
class Scheme < ActiveRecord::Base
# ...
accepts_nested_attributes_for :scheme_custom_issue_field_definitions_attributes
# ...
end

using last after model included doesnt work

Im stuck (still very new to Rails), and cant figure out why its not working:
I have:
class Message < ActiveRecord::Base
attr_accessible :updated_at
has_many :categories_messages
has_many :categories, through: :categories_messages
end
class CategoriesMessage < ActiveRecord::Base
attr_accessible :category_id, :message_id
belongs_to :category
belongs_to :message
end
class Category < ActiveRecord::Base
attr_accessible :name
has_many :categories_messages
has_many :message, through: :categories_messages
end
#messagesPer = Category.all.includes(:messages).group('categories.id').order("COUNT(messages.id) DESC")
<% #messagesPer.each_with_index do |message, i| %>
<tr>
<td><%= i+1 %></td>
<td><%= message.name %></td>
<% if message.categories_messages.exists? %>
<td><%= message.messages.last.updated_at.to_s.to_date %></td>
<td><%= message.messages.first.updated_at.to_s.to_date %></td>
<td><%= message.messages.count %></td>
<% else %>
<td>0</td>
<td>0</td>
<% end %>
</tr>
<% end %>
So i want it to show :
the name of Category, date the last message was created , date first message was created, and all messages in that category.
ALl works fine, apart from the fact that it only shows the date when the first message was created, but never the last (still shows first date on the last).
What am i doing wrong?
UPDATE:
if i put
#messagesPer = Category.all.includes(:messages).group('categories.id')
it does show the right date for last and first messages but as soon as i add order it breaks...
I might be helpful to include the error information you get after adding an order clause to the query.
However, I can spot some odd things in the code. The CategoriesMessage model seems to be there simply to satisfy the condition that a category can have many messages and vice versa. You don't need a model for this many-to-many relationship though, Rails will handle this automatically for you.
Your models should be looking like this:
class Message < ActiveRecord::Base
attr_accessible :updated_at
has_and_belongs_to_many :categories
end
class Category < ActiveRecord::Base
attr_accessible :name
has_and_belongs_to_many :messages
end
And in your database you have these tables: messages, categories,categories_messages, where the last one is the join table which only contains columns for amessage_idand acategory_id`.
Then you can simply do something like this in your code:
category.messages.each { |message| puts message.updated_at }
Also see this Ruby on Rails tutorial article for more information. If this doesn't work for you, please post the exact error you get.

Rails View All records with same foreign key

Currently in my view for each customer I have this:
<p>
<b>Companyname:</b>
<%= #customer.companyname %>
</p>
<p>
<b>Licensecontact:</b>
<%= #customer.licensecontact %>
</p>
<p>
<b>Email:</b>
<%= #customer.email %>
</p>
<p>
<b>Phone:</b>
<%= #customer.phone %>
</p>
Under that i need to have a table showing all of the licenses associated with that particular customer. something like this:
<% #licenses.each do |l| %>
<tr>
<td><%= l.software.vendor %></td>
<td><%= l.software.title %></td>
<td><%= l.software.edition %></td>
<td><%= l.amount %></td>
</tr>
<% end %>
I have three tables, customers, licenses and softwares (I know they're named badly) and one license has many customers and many softwares.
You should be able to put something like this into your view:
<table>
<tr>
<th>Vendor</th>
<th>Title</th>
<th>Edition</th>
<th>Amount</th>
</tr>
<% #customer.licenses.each do |l| %>
<tr>
<td><%= l.software.vendor %></td>
<td><%= l.software.title %></td>
<td><%= l.software.edition %></td>
<td><%= l.amount %></td>
</tr>
<% end %>
</table>
From your description it's unclear how customers and licenses are linked together. One option is customer has many licenses, license belongs to one user:
class Customer < ActiveRecord::Base
has_many :licenses
# ...
end
class License < ActiveRecord::Base
belongs_to :customer
# ...
end
another option is HABTM (you've said 'one license has many customers' and 'table showing all of the licenses associated with that particular customer' which hints me to this):
class Customer < ActiveRecord::Base
has_and_belongs_to_many :licenses
# ...
end
class License < ActiveRecord::Base
has_and_belongs_to_many :customers
# ...
end
Have you done any tutorials?
Your text contradicts you: you say 'One license has many softwares', but your code says 'License l has one software, and I want to display the name, title and edition'.
Use belongs_to and has_many. On which tables I cannot tell you, because your code syas the opposite of the last line you write. But these keywords you need to lookup in the docs, to understand how they work and which migrations to make.
Then, if you made the relations in the Models, then you can just call it the way you wrote it down in your second code-part.

Select data from two tables and listing

I have following structure:
class User < ActiveRecord::Base
has_many :Hobbies, :dependent => :destroy
accepts_nested_attributes_for :hobbies, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
end
class Hobby < ActiveRecord::Base
belongs_to :User
end
In my Users_controller.rb
def index
#data = User.all(:joins => :hobbies)
end
In index.html.erb
<% for item in #data %>
<tr>
<td><%= item.id %></td> #from table Users
<td><%= item.hobby_name %></td> #from table Hobbies
</tr>
<% end %>
And this gives me an error undefined method `hobby_name' for # User:0x103cf7480>
I thought that I have that associations right, but this error makes confused... Can you help me someone, please, where could be a problem?
You must specify the relation, your object doesn't have an attribute called hobby_name, it has an association to multiple hobbies, and each hobby has an attribute called hobby_name
So:
<% item.hobbies.each do |h| %>
<%= h.hobby_name %>
<% end %>