Show Name instead of ID in a HABTM relationship - ruby-on-rails-3

Excuse me if I'm being too much of a beginner but none of the other related answers worker.
I want to show the category name that the links belong to instead of the id.
Here's the migration.
class CreateCategoriesLinks < ActiveRecord::Migration
def self.up
create_table :categories_links, :id => false do |t|
t.references :category
t.references :link
end
end
def self.down
drop_table :categories_links
end
end
The categories model
class Category < ActiveRecord::Base
has_and_belongs_to_many :links
end
The links model
class Link < ActiveRecord::Base
has_and_belongs_to_many :categories
end
And here's what's in the links controller under index and show
#categories = Category.find(:all, :order => 'name')
and here's what's in the index right now but, I've tried every permutation of this that I could find.
<%= link.category.name %>
If it put <%= link.category_ids %>, it'll show the ids.

Try:
<% link.categories.each do |cat| %>
<%= cat.name %><br>
<% end %>

Related

Form not displayed correctly

i have a form consists of the following models
Employee.rb
class Employee < ActiveRecord::Base
attr_accessible :employee_number, :joining_date, :first_name, :middle_name, :last_name,
:gender, :job_title, :employee_department_id, :qualification, :experience_detail,
:experience_year, :experience_month, :status_description, :date_of_birth, :marital_status,
:children_count, :father_name, :mother_name, :husband_name, :blood_group, :nationality_id,
:home_address_line1, :home_address_line2, :home_city, :home_state, :home_pin_code,
:office_address_line1, :office_address_line2, :office_city, :office_state, :office_pin_code,
:office_phone1, :office_phone2, :mobile_phone, :home_phone, :email, :fax, :user_id,
:reporting_manager_id, :employee_grade_id, :office_country_id,
:home_country_id, :employee_category, :employee_position_id
belongs_to :employee_department
has_many :counselor_supervisors
belongs_to :employee_position
def to_label
full_name = first_name + " " + last_name
end
end
EmployeeDepartment.rb
class EmployeeDepartment < ActiveRecord::Base
attr_accessible :code, :name
has_many :employees
has_many :employee_positions
has_many :counselor_supervisors
has_many :batch_leadership_supervisors
def to_label
name
end
end
CounselorSupervisor.rb
class CounselorSupervisor < ActiveRecord::Base
attr_accessible :employee_id, :employee_department_id, :employee_position_id
belongs_to :employee
belongs_to :employee_department
has_many :batch_counselor_supervisors
def to_label
employee.to_label
end
end
BatchCounselorSupervisor.rb
class BatchCounselorSupervisor < ActiveRecord::Base
attr_accessible :counselor_supervisor_id , :employee_department_id , :counselor_batch_id,
:batch_counselor_advisors_attributes
has_many :batch_counselor_advisors
belongs_to :counselor_supervisor
belongs_to :employee_department
belongs_to :counselor_batch
accepts_nested_attributes_for :batch_counselor_advisors
end
Employee_position.rb
class EmployeePosition < ActiveRecord::Base
attr_accessible :position_title, :employee_department_id
has_many :employees
belongs_to :employee_department
def to_label
position_title
end
end
batch_counselor_supervisors/new.html.erb (part of the form which related to my question)
<%= simple_form_for(#batch_counselor_supervisor) do |f| %>
<%= f.error_messages %>
<%= f.association :employee_department, as: :select %>
<%= f.input :counselor_supervisor_id , collection: EmployeeDepartment.all, as: :grouped_select, group_method: :counselor_supervisors %>
<% end %>
the dropdown list appears like this:
If I added an employee which belongs to the first department "Business Administration", the form will be displayed correctly like this:
Update: after adding label_method: :to_label, so my form became like this :
<%= simple_form_for(#batch_counselor_supervisor) do |f| %>
<%= f.error_messages %>
<%= f.association :employee_department, as: :select %>
<%= f.input :counselor_supervisor_id ,
collection: EmployeeDepartment.all, as: :grouped_select, group_method: :counselor_supervisors, label_method: :to_label %>
<% end %>
the employee name displayed correctly but still the department name not displayed correctly as the following image:
Is this SQLite3 issue ? and What can I do in order to solve this if it sqlite3 issue or not.
From what I see, you only have an issue with the labels not being displayed correctly. Could you try to explicitly set the method on your input:
label_method: :to_label
For more information have a look at https://github.com/plataformatec/simple_form and search for *label_method*
What are the actual relevant rows in your Employee table and your EmployeePosition table?
In your Employee table you happen to have these 2 columns;
employee_position_id
employee_position.
Since employee_position is also a table name, it's bad/reduntant model structure which might be confusing your include method of the query. It's possible that in your tables, the rows are fully filled out to complete the first query, but not for any of your other queries even though you think it is.

Joining Three tables in Rails3

I am using http://guides.rubyonrails.org/ to learn ruby & rails. I have problem with joining three tables. , so I made new project as this example: http://guides.rubyonrails.org/association_basics.html#the-has_many_through-association i have three tables physicians, appointments & patients
Models:
physician.rb
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, :through => :appointments
attr_accessible :name
end
appointment.rb
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
attr_accessible :appointment_date, :patient_id, :physician_id
end
patient.rb
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, :through => :appointments
attr_accessible :name
end
I want to display the patient name, physician name & appointment_date. how to do this.
thanks in advance.
I believe, although I am not sure, that you are looking for the way to access objects and their associations in views. Is that correct?
I will give you an example using the Appointment model.
AppointmentsController
class AppointmentsController < ApplicationController
def index
#appointments = Appointment.includes(:physician, :patient).order(:appointment_date)
end
end
appointments#index (Haml syntax)
%ul
- #appointments.each do |appointment|
%li
= appointment.appointment_date
%br
%strong Physician:
= link_to appointment.physician.name, appointment.physician
%br
%strong Patient:
= link_to appointment.patient.name, appointment.patient
This would give you a list of appointments with their dates, physicians, and patients.
Is this the sort of help for which you were looking?
In Appointment Controller:
def index
#appointments = Appointment.order("appointment_date DESC")
end
In Appointments#index
<% for appointment in #appointments %>
<%= link_to appointment.patient.name, patients_path(appointment.patient) %>
Appointment for
<%= link_to appointment.physician.name, physician_path(appointment.physician) %>
<% if appointment.appointment_date? %>
<%= appointment.appointment_date %>
<% end %>
<% end %>

How to capture a comment's author then display in tooltip?

I have a form attached to profiles where short comments can be submitted. I want to capture the author's name though so I can display it in a tooltip when hovering over the comment's body.
In my create method in the controller I have:
def create
#comment = Comment.new(params[:comment])
#comment.save!
redirect_to profile_path(#comment.profile)
end
Inside my migration:
t.timestamps
t.integer :profile_id
t.string :author_id
t.string :body
Profile model:
belongs_to :user
accepts_nested_attributes_for :user
has_many :comments
Comment model:
belongs_to :profile
ProfilesController:
def show
#user = User.find(params[:id])
#profile = user.profile
#superlative = #profile.superlatives.new
end
And my form:
<%= form_for #comment do |f| %>
<%= f.hidden_field :profile_id, :value => #profile.id %>
<%= f.hidden_field :author_id, :value => "#{current_user.profile.first_name} #{current_user.profile.last_name}" %>
<%= f.text_field :body %>
<%= f.submit 'Add new' %>
<% end %>
I was thinking of linking the :author_id to current_user.profile.id and using that association to display :first_name and :last_name which are attributes of the profile. Or is there a simpler, better way?
UPDATE: I got it to display the name though I'm still curious if there's a better way.
Your solution looks fine, but I'd store the User (or whatever class current_user returns) instead of the Profile:
In app/models/comment.rb:
class Comment < ActiveRecord::Base
belongs_to :profile
belongs_to :author, :class_name => "User", :foreign_key => "author_id"
... rest of the code ...
end
You then change your migration to:
t.integer :author_id
and your controller method to:
def create
#comment = Comment.new(params[:comment].merge(:author_id => current_user.id))
#comment.save!
redirect_to profile_path(#comment.profile)
end
In your view (I used the title attribute do create a tooltip, but feel free to use whatever method you like):
<div class="comment" title="<%= #comment.author.profile.first_name %> <%= #comment.author.profile.last_name %>">
<%= #comment.body %>
</div>
I would suggest something like this:
In your routes.rb create a nested resource for comments
resources :users do
resources :comments
end
In your User model
class User
has_many :comments
end
In your Comment model
class Comment
belongs_to :user
end
In your CommentsController in the new and create methods
#comment = User.find(params[:user_id]).comments.new(params[:comment])
So the comment automagically gets created as belonging to that User and you don't have to pass anything around.
Then, in your Comment view, you could just call its owners name
#comment.user.first_name

Possible to chain queries in Rails 3?

I have something like the following
class Group < ActiveRecord::Base
has_many :group_users
end
class GroupUser < ActiveRecord::Base
belongs_to :user, :group
end
class User < ActiveRecord::Base
has_many :group_users
end
The reason I'm not using has_many_through is because the group_user class has more information than just a link table, so I want to be able to access those values.
What I would like to do though is pass #groups to the page and loop through the group users but get at the user object as well
so
<% #groups.each do |group| %>
<%= group.group_user.user.name %>
<% end %>
Here is how I would do it:
User Model
class User < ActiveRecord::Base
has_many :memberships
has_many :groups, :through => :memberships
end
Group Model
class Group < ActiveRecord::Base
has_many :memberships
has_many :users, :through => :memberships
end
Membership Model
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :group
end
Controller
def show
#groups = Group.all
end
View
<% #groups.each do |group| %>
<% group.users.each do |user| %>
<%= user.name %>
<% end %>
<% end %>
There are probably a few ways to do it, but this should get you started.
Hope this helps!
If you want to access attributes from the GroupUser model, just do this:
<% #groups.each do |group| %>
<% group.group_users.each do |group_user| %>
<%= group_user.attribute_name %>
<%= group_user.user.name
<% end %>
<% end %>
To make this more efficient from the SQL side of things you can use eager loading:
Group.all(:includes => [:group_users => :user])
F

Using Rails Gem Active Admin with Associations

I'm trying out the new Rails gem http://activeadmin.info/ and it's working great! However I can't find any documentation on how to use it across associations. For example:
class Membership < ActiveRecord::Base
belongs_to :course
belongs_to :person
class Course < ActiveRecord::Base
has_many :memberships
has_many :people, :through => :memberships
class Person < ActiveRecord::Base
has_many :memberships
has_many :courses, :through => :memberships
The membership join table includes some extra data as well (ie: attendance). I'm trying to show the membership with both the course and student name - and allow filtering / sorting on those names. As far as I have found, Active Admin doesn't work across associations. Has anyone else been successful in doing that, or found another gem that does? Thanks so much!
ingredient.rb
class Ingredient < ActiveRecord::Base
has_and_belongs_to_many :products, :join_table => :ingredients_products
end
product.rb
class Product < ActiveRecord::Base
has_and_belongs_to_many :ingredients, :join_table => :ingredients_products
end
don't forget the migrations for the joining table (:id to false!)
class CreateProductsIngredients < ActiveRecord::Migration
def self.up
create_table :ingredients_products,:id => false do |t|
t.integer :product_id
t.integer :ingredient_id
t.timestamps
end
end
def self.down
drop_table :products_ingredients
end
end
Now define the form in you ActiveAdmin resource, override the default
ActiveAdmin.register Product do
form do |f|
f.inputs "Details" do
f.input :product_name
f.input :brand
f.input :ingredients # don't forget this one!
end
end
I've been playing with ActiveAdmin for a while now, here's how I managed to get associations to work in Indexes and Forms.
I've just guessed some of your model columns below. Also note, in the form. The 'person' section will show all the columns for editing, whereas the 'course' section will just show the specified column.
ActiveAdmin.register User do
index do
column :id
column :name
column :attendance
column :person do |membership|
membership.person.name
end
column :course do |membership|
membership.course.name
end
default_actions
end
form do |f|
f.inputs "Membership" do
f.input :name
f.input :created_at
f.input :updated_at
end
f.inputs :name => "Person", :for => :person do |person|
person.inputs
end
f.inputs :name => "Course", :for => :course do |course|
course.input :name
end
f.buttons
end
end
I haven't tested this, but you should be able to apply these ideas to your case. It's working for mine.
Update: I've just read your question again and noted that you're wanting to be able to sort on the association column. I've just checked my implementation and this indeed is not working. My answer may be useless to you but I'll leave it here anyway (might help someone else).
I've just started using this gem myself, and while I haven't gotten around to showing association information, here's how you create a form for associations:
form do |f|
f.inputs
f.has_many :associations do |association|
association.inputs
end
f.buttons
end
That will give you a basic form with scaffolding.
ingredient.rb
class Ingredient < ActiveRecord::Base
has_and_belongs_to_many :products, :join_table => :ingredients_products
end
product.rb
class Product < ActiveRecord::Base
attr_accessible ingredient_ids
has_and_belongs_to_many :ingredients, :join_table => :ingredients_products
end
migration_xxx.rb
class CreateProductsIngredients < ActiveRecord::Migration
def self.up
create_table :ingredients_products,:id => false do |t|
t.integer :product_id
t.integer :ingredient_id
t.timestamps
end
end
def self.down
drop_table :products_ingredients
end
end
products.rb
ActiveAdmin.register Product do
form do |f|
f.inputs "Details" do
f.input :product_name
f.input :brand
f.input :ingredients
end
end
...
end