I am providing my active records below. In view/users/show I want to display any project the user is working on, through blueprints. When a user adds multiple blueprints to a project, the project is showing up multiple times. I tried some validate_uniqueness options to no avail.
class Blueprint < ActiveRecord::Base
attr_accessible :id, :name, :project_id, :user_id, :loc
belongs_to :user
belongs_to :project
has_many :comments
end
class Project < ActiveRecord::Base
attr_accessible :id, :name
has_many :blueprints
has_many :users, :through => :blueprints
has_many :comments
end
class User < ActiveRecord::Base
attr_accessible :id, :name
has_many :blueprints
has_many :projects, :through => :blueprints
end
Here is the view code that is displaying multiple values of the same project.
<% #user.blueprints.each do |blueprint| %>
<tr>
<td><%= link_to blueprint.project.name, project_path(blueprint.project) %></td>
</tr>
<% end %>
Thanks!
Try setting uniq option to true in user's projects relation like this
class User < ActiveRecord::Base
has_many :projects, :through => :blueprints, :uniq => true
end
Since you already have the projects association in the User, why don't you loop through the user's projects instead of the blueprints.
<% #user.projects.each do |project| %>
<tr>
<td><%= link_to project.name, project_path(project) %></td>
</tr>
<% end %>
Related
I have a setup where an author has many sources (and visa versa) through authorships.
I am working on the source form and would like to have a selection dropdown where a user can select multiple authors to be associated with a given source.
My author model looks like this:
class Author < ApplicationRecord
belongs_to :user
has_many :authorships
has_many :sources, through: :authorships
def last_first
"#{last_name}, #{first_name}"
end
...
end
My source model:
class Source < ApplicationRecord
belongs_to :user
has_many :authorships
has_many :authors, through: :authorships
...
end
And my authorship model:
class Authorship < ApplicationRecord
belongs_to :source
belongs_to :author
end
I tried this at first:
<%= f.collection_select(:author_ids, Author.all, :id, :last_first, multiple: true) %>
But I got this strange error: Could not find the source association(s) "author" or :authors in model Authorship. Try 'has_many :authors, :through => :authorships, :source => <name>'. Is it one of ?
I consulted many SO posts like this, this, and this, but to no avail.
Can anyone help me figure out what I'm doing wrong? The collection_select documentation is not much help.
I ended up solving this with a collection_check_boxes like this:
<%= f.collection_check_boxes :author_ids, Author.all, :id, :last_first do |b| %>
<div class="field form-check" style="display: block">
<%= b.check_box class: "form-check-input" %>
<%= b.label class: "form-check-label" %>
</div>
<% end %>
Not a dropdown, but it's functional and saves!
I am trying to sort comments into events using a has_many :through association using checkboxes however the selected events are not saved. Here are my models:
class Comment < ActiveRecord::Base
has_many :categorizations
has_many :events, :through => :categorizations
end
class Event < ActiveRecord::Base
has_many :categorizations
has_many :comments, :through => :categorizations
end
class Categorization < ActiveRecord::Base
belongs_to :comment
belongs_to :event
end
My comments form looks like this:
<%= simple_form_for [#post, #comment] do |f| %>
<%= f.input :title %>
<%= f.association :events, :as => :check_boxes %>
<%= f.submit "Save" %>
After reading this answer, I added this to my event and comment controllers with no luck:
def comment_params
params.require(:comment).permit(:post_id, :title, :categorization_ids => [])
end
Try:
def comment_params
params.require(:comment).permit(:post_id, :title, :event_ids => [])
end
It's hard to know what's going on though without recreating it or seeing server logs, Hopefully this will solve it.
I have 3 tables: employees, projects and teams
Employee has_many :projects, :through => :teams
Project has_many :employees, :through => :teams
I added roles_id column to teams table.
Team belongs_to :role
Now I'm listing the projects, who's on the team and their role.
<% #project.employees.each do |employee| %>
<tr>
<td><%= employee.employee_full_name %></td>
<td><%= employee.team.role.rolecode %></td>
But, the role line is incorrect.
Any suggestions?
Your code has two problems:
Your associations are incomplete. See this explanation that
explains how to model a has_many :through;
An employee has_many teams, so you cannot say employee.team.
The solution for your first problem is that you have to define the following associations:
class Employee
has_many :teams
has_many :projects, :through => :teams
end
class Project
has_many :teams
has_many :employees, :through => :teams
end
class Team
belongs_to :role
belongs_to :employee
belongs_to :project
end
As for you second problem: an employee can belong to more than one team, so you cannot do employee.team. You can only do employee.teams. The solution would be to change your iteration like this:
<% #project.teams.each do |team| %>
<tr>
<td><%= team.employee.employee_full_name %></td>
<td><%= team.role.rolecode %></td>
roles_id => role_id ?) or belongs_to :role, :foreign_key => "roles_id"
I am working on a project involving three models (recipient, award, announcer) and need to have a nested attributes when issuing an award by an announcer to multiple recipients. For an example, award form need to have the ability to do 3 things:
Can add multiple-recipients (i.e. "add recipient", "remove recipient") - nested attributes
After creating a new award, the award will be posted into recipient's profile.
Enables future polling of #recipient.awards and #announcer.awards
Really struggle in terms of how to smartly solve this problem. The following data structure kind of made sense, however can not do "accepts_nested_attributes_for :recipients" in the award form. Can you help? Many thanks in advance.
class Recipient < ActiveRecord::Base
has_many :awards
has_many :announcers, :through => :awards
end
class Announcer < ActiveRecord::Base
has_many :awards
has_many :recipients, :through => :awards
end
class Award < ActiveRecord::Base
belongs_to :announcer
belongs_to :recipient
end
You're just about there. The main issue is that you're trying to create recipient objects in the form rather than just creating a relationship between the award and another object (user). You could do something like this:
class User < ActiveRecord::Base
has_many :recipients
has_many :awards, :through => :recipients
end
# this is your relationship between an award and a user
class Recipient < ActiveRecord::Base
belongs_to :user
belongs_to :award
end
class Award < ActiveRecord::Base
has_many :recipients
has_many :users, :through => :recipients
belongs_to :announcer
accepts_nested_attributes_for :recipients, :allow_destroy => true
end
class Announcer < ActiveRecord::Base
has_many :awards
has_many :recipients, :through => :awards
end
Then you would just do a nested form that would build the recipients_attributes array:
<%= form_for #award do |f| %>
<%= f.text_field :name %>
<div id="recipients">
<% #award.recipients.each do |recipient| %>
<%= render :partial => '/recipients/new', :locals => {:recipient => recipient, :f => f} %>
<% end %>
</div>
<%= link_to_function 'add recipient', "jQuery('#recipients').append(#{render(:partial => '/recipients/new').to_json})" %>
<% end %>
And, to keep it DRY just push the nested part into a partial:
# app/views/recipients/_new.html.erb
<% recipient ||= Recipient.new %>
<%= f.fields_for 'recipients_attributes[]', recipient do |rf| %>
<%= rf.select :user_id, User.all %>
<%= fr.check_box '_delete' %>
<%= fr.label '_delete', 'remove' %>
<% end %>
Obviously the User.all call isn't ideal so maybe make that an autocomplete.
Below are my two model classes
class Patient < ActiveRecord::Base
belongs_to :user, :dependent => :destroy
has_many :enrollments, :dependent => :destroy
has_many :clients, :through => :enrollments
accepts_nested_attributes_for :user
accepts_nested_attributes_for :enrollments
attr_accessible :user_attributes,:enrollments_attributes, :insurance
end
class Enrollment < ActiveRecord::Base
belongs_to :client
belongs_to :patient
attr_accessible :client_id, :patient_id, :patient_id, :active
end
In my patient form I would like to have a multi select box where a patient can be assigned to clients. Is there a way this can be done so I don't have to have any logic in the
controller except for
#patient = Patient.new(params)
#patient.save
I have tried this:
<%= patient_form.fields_for :enrollments do |enrollments_fields| %>
<tr>
<td class="label">
<%= enrollments_fields.label :client_id %>:
</td>
<td class="input">
<%= enrollments_fields.collection_select(:client_id, #clients, :id, :name, {}, :multiple => true) %>
</td>
</tr>
<% end %>
But it only saves the first client. If I remove the multiple part, it functions but I can only select 1 client!
The html value of the select is:
I ended up doing the following:
<%= check_box_tag "patient[client_ids][]", client.id, #patient.clients.include?(client) %>
I am not sure if this is the best way...any comments (I had to update my model to include attr_accessible :client_ids
In Rails 3 (not sure about previous versions) you don't even need to use accepts_nested_attributes_for to accomplish this. You can simply remove all the view code you listed and replace it with the following:
<%= patient_form.select(:client_ids, #clients.collect {|c| [ c.name, c.id ] }, {}, {:multiple => true})%>
Rails will do its magic (because of you named the select "client_ids") and it will just work.
Instead of
:client_id
in the collection_select, try
"client_id[]"
The second form specifies that you're accepting an array of IDs for the attribute rather than a single one.
Here's a good resource on the usage of the select helpers in forms: http://shiningthrough.co.uk/Select-helper-methods-in-Ruby-on-Rails