Rails, Nested Models, Arrays, Iterating through a "for" loop - ruby-on-rails

I'm new to Ruby and following this novawave tutorial (a little older) on creating an internal messaging system.
http://www.novawave.net/public/rails_messaging_tutorial.html
I'm currently attempting to list the sent messages, but I am unable to properly link to the message "recipients." Here is the for loop:
<% for message in #messages %>
<tr>
<td><%= message.user.name %></td>
<td><%= message.subject %></td>
<td><%= message.recipients.map(&:user).to_sentence %></td>
I'm getting an "unitialized constant" error for "recipients" I have three models: User, Message_Copy, and Message.
Message Model
belongs_to User,
has_many :recipients, :through => :message_copies
Message_Copy model
belongs_to Message and recipient
User model
has_many of the other models.
I've noticed this same problem in other applications. When I iterate through the array, if the primary model "belongs to" another model, I can access that model. For example, I can access the User model because the Message model "belongs_to" the User model. Hence I can use message.user.name. But I cannot access the attributes of a model that "belongs_to" the primary model. So I cannot access the Message_Copy model attributes in this array. So message.recipient.id will return an error. This question may have already been answered, and I may just be making a series of easy mistakes. But I'm confused and was hoping someone could help and possibly explain what I'm missing. Please let me know if more informaiton is required. Thank you
Apologies, here is more code from the models:
User Model
class User < ActiveRecord::Base
attr_accessor :password
attr_accessible :name, :email, :password, :password_confirmation
has_many :sent_messages, :class_name => "Message"
has_many :received_messages, :class_name => "MessageCopy", :foreign_key =>"recipient_id"
has_many :folders
class MessageCopy < ActiveRecord::Base
belongs_to :message
belongs_to :recipient
belongs_to :folder
delegate :user, :created_at, :subject, :body, :recipients, :to => :message
end
class Message < ActiveRecord::Base
belongs_to :user
has_many :message_copies
has_many :recipients, :through => :message_copies
before_create :prepare_copies
attr_accessor :to # array of people to send to
attr_accessible :subject, :body, :to
def prepare_copies
return if to.blank?
to.each do |recipient|
recipient = User.find(recipient)
#recipient=recipient
message_copies.build(:recipient_id => recipient.id, :folder_id => recipient.inbox.id)
end
end
end
I noticed this worked:
<%= message.message_copies %>
Instead of the above code:
<td><%= message.recipients %></td>
I don't understand this because the tutorial can use "recipients" and also because I can reference the Message_Copy model through Recipients in other methods.
But
<%= message.message_copies %>
also just returns an array, and I'm unclear how I can reach the specific attributes in the message_copy model, since
<%= message.message_copies.content %>
does not work.
Thank you! I'll post more code if necessary

Related

Selecting 'has_many through' associations in Active Admin

I've seen several questions asked about this along the same vein, e.g.
Using HABTM or Has_many through with Active Admin
but I'm still struggling to get things to work (I've tried multiple ways at this point).
My models (slightly complicated by the 'technician' alias for the user model):
class AnalysisType < ActiveRecord::Base
has_many :analysis_type_technicians, :dependent => :destroy
has_many :technicians, :class_name => 'User', :through => :analysis_type_technicians
accepts_nested_attributes_for :analysis_type_technicians, allow_destroy: true
end
class User < ActiveRecord::Base
has_many :analysis_type_technicians, :foreign_key => 'technician_id', :dependent => :destroy
has_many :analysis_types, :through => :analysis_type_technicians
end
class AnalysisTypeTechnician < ActiveRecord::Base
belongs_to :analysis_type, :class_name => 'AnalysisType', :foreign_key => 'analysis_type_id'
belongs_to :technician, :class_name => 'User', :foreign_key => 'technician_id'
end
I have registered an ActiveAdmin model for the AnalysisType model and want to be able to select (already created) Technicians to associate with that AnalysisType in a dropdown/checkbox. My ActiveAdmin setup currently looks like:
ActiveAdmin.register AnalysisType do
form do |f|
f.input :analysis_type_technicians, as: :check_boxes, :collection => User.all.map{ |tech| [tech.surname, tech.id] }
f.actions
end
permit_params do
permitted = [:name, :description, :instrumentID, analysis_type_technicians_attributes: [:technician_id] ]
permitted
end
end
Whilst the form seems to display okay, the selected technician does not get attached upon submitting. In the logs I'm getting an error 'Unpermitted parameters: analysis_type_technician_ids'.
I've tried multiple ways of doing this following advice in other related SO pages but am always coming up against the same issue, i.e. unpermitted parameterd of some nature. Can anyone point out what I am doing wrong? (I'm using Rails 4 by the way)
Managing the association via has_and_belongs_to_many or has_many relations
does not require the use of accepts_nested_attributes_for. This type of form
input is managing the Technician IDs associated with the AnalysisType record.
Defining your permitted parameters and form like the following should allow
those associations to be created.
ActiveAdmin.register AnalysisType do
form do |f|
f.input :technicians, as: :check_boxes, collection: User.all.map { |tech| [tech.surname, tech.id] }
f.actions
end
permit_params :name, :description, :instrumentID, technician_ids: []
end
In the case where the creation of new Technician records is required that is
when the accepts_nested_attributes_for would be used.
Note: Updated answer to match comments.

Traversing Through Multiple Associations (Rails)

I am a little stuck on this one. I would appreciate input.
Overview
I am trying to get the output I require in this friendship model i.e. the files the current user's friends have uploaded.
Models
Like all other friendship models, User is self-referencing as :friend.
class Share < ActiveRecord::Base
belongs_to :user
belongs_to :friend, :class_name => "User"
end
This is my Paperclip model:
class Upload < ActiveRecord::Base
belongs_to :user
has_attached_file :document
end
This one is generated through Devise:
class User < ActiveRecord::Base
attr_accessor :login
has_attached_file :image, :styles => { :medium => "120x120!" }
has_many :uploads
has_many :shares
has_many :friends, :through => :shares
has_many :inverse_shares, :class_name => "Share", :foreign_key => "friend_id"
has_many :inverse_friends, :through => :inverse_shares, :source => :user
end
Attempts
The furthest I have gotten into would be the level in which I am able to output the user's friends' :username(s), where #check = current_user in the controller:
<% #check.shares.each |j| %>
<%= j.friend.username %>
<% end %>
Question
How do I output the :file_name, :file_type, and :document of each of the current user's friends? I intend to have my page look like this:
User's Friend 1 Files
File Name
File Type
Document
User's Friend 2 Files
File Name
File Type
Document
Thank you.
Per the Paperclip documentation :
Paperclip will wrap up to four attributes (all prefixed with that
attachment's name, so you can have multiple attachments per model if
you wish) and give them a friendly front end. These attributes are:
<attachment>_file_name
<attachment>_file_size
<attachment>_content_type
<attachment>_updated_at
Given that, and with your attachment name of "document" :
<% current_user.shares.each do |share|%>
<%= share.friend.username %>
<% share.friend.uploads.each do |upload| %>
<%= upload.document_file_name %>
<%= upload.document_content_type %>
<% end %>
<% end %>

Retrieve information from associated model

I have 3 models:
class Brand
attr_accessible :obs, :site, :title
has_many :equipments
end
class Equipment
attr_accessible :brand_id, :category_id, :lending_id
belongs_to :brand
has_many :lendings
end
class Lending
attr_accessible :equipment_id
belongs_to :equipment
end
I'm trying to show the brand of an associated equipament:
Brand: <%= #lending.equipment.brand %>
that command show this: Brand:0xab7f2c8
As you can see, there's no association between brand and lending models and for me its strange if i do that. I want to use the equipment/brand association to retrieve the :title information and show it on my lending view.
Can anyone help me?
You can either use a delegate in Lending:
delegate :brand, :to => :equipment, allow_nil: true
Or you can setup a has-one-through association in Lending:
has_one :branch, :through => :equipment
Either way, you can now call branch directly from a Lending instance, and work on it (almost) as if it were a regular association.
Use delegate
class Lending
attr_accessible :equipment_id
belongs_to :equipment
delegate :brand, :to => :equipment, :allow_nil => true
end
now you can use
<%= #lending.brand.title%>

How to reference attributes in deep associations

Summary
Rails 3.2 with RefineryCMS 2.0. These are my pseudocode models:
Industry
name
has_many companies
has_many works through companies
Company
name
has_many works
belongs_to industry
Work
name
belongs to company
From an instance of Work, I can say work.company.name and get a the name of the associated company. I would expect it to follow that I could also say company.industry.name without a problem. However, I am getting an unhelpful error:
wrong constant name Refinery:Industries
What I would ultimately like to do is follow my associations all the way up ie work.company.industry.name, but the chain is broken between company and industry it seems.
What am I doing wrong here? Here's my code in more detail.
Code
Here are my models. Any idea what would prevent me from accessing industry attributes from an associated company given that industries have_many companies (companys lol) and companies belong_to an industry? Any help would be much appreciated.
Industry Model
module Refinery
module Industries
class Industry < Refinery::Core::BaseModel
...
attr_accessible :name, :description, :position
has_many :companys, :class_name => '::Refinery::Companys::Company', :dependent => :nullify
has_many :works, :through => :companys
end
end
end
Company Model
module Refinery
module Companys
class Company < Refinery::Core::BaseModel
...
attr_accessible :name, :position, :industry_id
has_many :works, :class_name => '::Refinery::Works::Work', :dependent => :destroy
belongs_to :industry, :class_name => '::Refinery:Industries::Industry'
end
end
end
Work Model
module Refinery
module Works
class Work < Refinery::Core::BaseModel
...
attr_accessible :name, :description, :position, :company_id
belongs_to :thumbnail, :class_name => '::Refinery::Image'
belongs_to :Company, :class_name => '::Refinery::companys::company'
end
end
end
Then in my erb file I'm doing this:
<% #works.each do |work| %>
...
<h5>
<%= work.company.name %>
</h5>
<% end %>
That one works.
This one gives me an error though:
<% #clients.each do |client| %>
<h5>
<%= client.industry.name %>
</h5>
<% end %>
That error reads:
wrong constant name Refinery:Industries
There is at least a double colon missing in your Company model:
belongs_to :industry, :class_name => '::Refinery:Industries::Industry'
should be
belongs_to :industry, :class_name => '::Refinery::Industries::Industry'
I haven't really looked at the rest of the code, but this is a first error.

Getting a value from a table through a foreign key in Rails?

Hi I have created two models,
class Fixture < ActiveRecord::Base
attr_accessible :away_score, :away_team_id, :home_score, :home_team_id, :result, :week
belongs_to :team, :class_name => Team
end
class Team < ActiveRecord::Base
attr_accessible :form, :name
has_many :fixtures, :class_name => Fixture, :foreign_key => :home_team_id
has_many :fixtures, :class_name => Fixture, :foreign_key => :away_team_id
end
In my fixtures table I store a team_id in the home_team_id and away_team_id columns.
Then in my fixtures/show.html.erb I show the id stored
<p>
<b>Home team:</b>
<%= #fixture.home_team_id %>
</p>
How can I show the team.name from the teams table by getting the team.id stored in the fixtures table?
I need to change this line <%= #fixture.home_team_id %> to something else but not sure what?
http://guides.rubyonrails.org/association_basics.html#belongs_to-association-reference
With belongs_to you can access it with: #fixture.team since your defining a one to many relationship it should never have both home_team_id and away_team_id and will access the appropriate one.

Resources