Rails 5 many to many index - ruby-on-rails

I am having a problem in the eyes when presenting the data.
I have 3 user models, sponsors and pets Result that sponsors in a table join between users and pets that are nan, my problem is in the hour to show all the sponsors of the mascot in sight and achievement but in a wrong way to La time to msotrar the data. I hope you can tell me how to fix it. Thank you.
Index.html.erb
<h1>Sponsors#index</h1>
<table class="table table-bordered table-hover table-striped" id="histories">
<thead>
<tr>
<th>Mascota</th>
<th>Padrinos</th>
<th>Apadrinar</th>
</tr>
</thead>
<tbody>
<% #pets.each do |pet| %>
<tr>
<td><%= pet.name %></td>
<td>
<% #users.each do |user| %>
<% #sponsors.each do |sponsor| %>
<% if user.id == sponsor.user_id and pet.id == sponsor.pet_id %>
<%= user.email%>
<% else %>
<p>No Tengo Padinos =-( </p>
<% end %>
<% end %>
<% end %>
</td>
<td><button>Apadrinar</button></td>
</tr>
<% end %>
</tbody>
</table>
My controller has the three models that I am sending to view.
def index
#sponsors = Sponsor.all
#users = User.all
#pets = Pet.all
end
pet.rb
class Pet < ApplicationRecord
has_many :adoptions
belongs_to :race, required: false
has_many :users, through: :sponsors
end
user.rb
class User < ApplicationRecord
has_many :pets, through: :sponsors
end
sponsor.rb
class Sponsor < ApplicationRecord
belongs_to :user
belongs_to :pet
end
The output that now shows me the attachment in the image.enter image description here
I also wonder if there is a better way to make the query, to show the respective data.
Another thing is how would I do to no longer be able to sponsor pets that I have already given a sponsor?

You are using a through table to join users and pets, but your associations aren't setup properly. For a through model, you have to have_many of the through table along with a has_many: :through association. Your associations should look like this:
class Pet < ApplicationRecord
has_many :adoptions
belongs_to :race, required: false
**has_many :sponsors**
has_many :users, through: :sponsors
end
class User < ApplicationRecord
**has_many :sponsors**
has_many :pets, through: :sponsors
end

Afther working and following diferent recomendations here is my solution.
<% #pets.each do |pet| %>
<tr>
<td> <%= pet.name %></td>
<td>
<% if pet.sponsors.any? %>
<% pet.sponsors.each do |sponsor| %>
| <%= sponsor.user_email %> |
<% end %>
<% else %>
<p>No Tengo Padinos =-( </p>
<% end %>
</td>
<td>
<%= link_to "Apadrinar", {:controller => "sponsors", :action => "new", :mascot => pet.id }%>
</td>
</tr>
<% end %>
I changed also my models.
sponsor.rb
class Sponsor < ApplicationRecord
belongs_to :user
belongs_to :pet
has_many :gifts
delegate :email, to: :user, prefix: true, allow_nil: true
end
user.rb
class User < ApplicationRecord
has_many :sponsors
has_many :pets, through: :sponsors
end
pet.rb
class Pet < ApplicationRecord
has_many :sponsors
has_many :users, through: :sponsors
end
And finally mi index on Controller.
sponsors_controller.rb
def index
# #sponsors = Sponsor.all
# #users = User.all
# #pets = Pet.all
# #pets_no_sponsors = Pet.where.not(id: Sponsor.select("pet_id")).select("id")
#pets = Pet.includes(:sponsors)
end
By making a delegation now I only make a query which sends everything necessary to my index.

Related

I want to get the data from many to many table

I want to get the data from many to many relationship table (Tag-Service-Category) like this below in tag/show.html.erb.
class Tag < ActiveRecord::Base
has_many :service_tags
has_many :services, through: :service_tags
end
class ServiceTag < ActiveRecord::Base
belongs_to :service
belongs_to :tag
end
class Service < ActiveRecord::Base
has_many :service_tags
has_many :tags, through: :service_tags
has_many :service_categories
has_many :categories, through: :service_categories
end
class ServiceCategory < ActiveRecord::Base
belongs_to :service
belongs_to :category
end
class Category < ActiveRecord::Base
has_many :service_categories
has_many :services, through: :service_categories
end
I wrote the code like this, but it`s not working.
#tag = Tag.find(params[:id])
<% #tag.services.each do |service| %>
<% service.categories.each do |category| %>
<span class="category" class="<%= category.id %>"><%= category.name %></span>
<% end %>
<% end %>
controllers/tags_controller.rb
class TagsController < ApplicationController
def show
#tag = Tag.find(params[:id])
#tags = Tag.all
end
end
Although you have the db relationships correct, you'll still need to call out the connecting model. Because you're doing a double many to many relationship you'll need to create an in-between array. Try adding this to your view:
<% services_array = [] %>
<% #tag.service_tags each do |service_tag| %>
<% services_array << service_tag.service %>
<% end %>
<% services_array.each do |service| %>
<span class="category">
<%= service.service_category.category.id %>
<%= service.service_category.category.name %>
</span>
<% end %>

Many to many associations

Hello I am having a hard time debugging my code. What I need to do is create a page where the user will type in a last name and the system will return information related to it. I am stuck and can not debug it any help or guidance would be greatly appreciated
Model of my Customer table
class Customer < ActiveRecord::Base
has_many :booking
has_many :room, :through => :booking
def mail_list
"#{first} - #{last} - #{maillist}"
end
end
Here is the page that should display the data after the user enters a last name
<center><table width = 65% border = 1>
<tr> <th> Customer Name</th><th> Room Number </th> <th> Cost </th></tr>
<% #customers_list.each do |m| %>
<% p = m.cost %>
<tr> <td> <%= m.name %> </td> <td> <%= m.roomnumber %> </td> <td> <%= m.cost %> </td> </tr>
<% end %> </table> </center><br /> <br />
Here is the page that takes in the last name
<%= form_tag(bookin_bookout_path, :controller => "bookin", :action => "bookout", :method => "post") do %>
<div class="field">
<%= label_tag :Customer_Name %><br />
<%= text_field_tag :customer_name_in %>
</div>
<div class="actions">
<%= submit_tag "Submit Customer Name" %>
</div>
<% end %>
Model of my rates table
class Rate < ActiveRecord::Base
validates :season, :room, :cost, presence: true
has_many :booking
has_many :room, :through => :booking
end
Here is the Controller of my bookin that runs the user putting in last name and posting results
class BookinController < ApplicationController
def bookin
def bookout
#customer_name = params[:customer_name_in]
r = Customer.find_by_last(#customer_name)
#room_list = r.rooms
end
end
end
Here is the Model of my room table
class Room < ActiveRecord::Base
has_many :booking
has_many :customer, :through => :booking
end
Here is the Model of my booking table
belongs_to :room
belongs_to :customer
belongs_to :rate
end
Here is my routes
Hotel::Application.routes.draw do
resources :bookings
get "bookin/bookout"
post "bookin/bookout"
get "listin/listout"
resources :customers
get "manin/manout"
resources :users
get "mailin/mailout"
get "showin/showout"
resources :roomins
get "ratein/rateout"
get "foodin/foodout"
resources :apples
resources :rooms
resources :menus
resources :rates
get "starter/home"
resources :foods
get "bookin/bookname"
post "bookin/bookname"
root 'starter#home'
end
You need to use pluralized model name with has_many, use this
has_many :bookings
has_many :rooms, :through => :bookings
You have not followed rails' convention over configuration in naming your models and controllers

Rails: Create form for #score while in different model no direct associations

I want to create a multiple form for editing scores from a different model.
The main model is a Formrule model that consists of a habtm association with a Scoretype model
and has a habtm association with a Room model.
Both models are used to query a Scores model resulting in a #scores instance. It is for this instance I want to create a form, but the problem is that no field_for are being created. I know that the #scores is populated correctly, but the form does not show up.
This is the form as I have it now
<%= form_tag '/scores/update_scores' do %>
<table>
<tr>...</tr>
<% for score in #scores %>
<% fields_for :scores, score do |score| %>
<tr>
<td>
<%= score.hidden_field(:form_id) %>
<%= score.hidden_field(:team_id) %>
<%= score.hidden_field(:scoretype_id) %>
</td>
<td>
<%= score.number_field :scorevalue %>
</td>
</tr>
<% end %>
<% end %>
</table>
<%= submit_tag 'Update' %>
<% end %>
And these are the Models:
Formrule
class Formrule < ActiveRecord::Base
belongs_to :form
has_and_belongs_to_many :scoretypes
has_and_belongs_to_many :rooms
has_many :teams, :through => :rooms
end
Scoretype
class Scoretype < ActiveRecord::Base
has_many :scores
has_and_belongs_to_many :formrules
end
Room
class Room < ActiveRecord::Base
has_many :teams
has_and_belongs_to_many :formrules
end
Team
class Team < ActiveRecord::Base
has_many :scores
belongs_to :room
belongs_to :group
end
Score
class Score < ActiveRecord::Base
belongs_to :form
belongs_to :team
belongs_to :scoretype
validates_uniqueness_of :id, :scope => [:team, :scoretype]
end
And finally, the used controller (Formrule)
def show
#formrule = Formrule.find(params[:id])
#scoretypes = #formrule.scoretypes.all.collect
#rooms = #formrule.rooms.all.collect
#teams = Team.find(:all, :conditions => {:room_id => #rooms})
#scores = Score.order("team_id").all(:conditions => {:scoretype_id => #scoretypes, :team_id => #teams})
...
end
Why is the form not showing up? any suggestions?
Thank you all in advance!
Try using <%= fields_for ... %> instead of <% fields_for ...%>.

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