I am trying to make an app with Rails 4.
I have a project model and a project invitations model.
Projects has many project invitations
Project invitations belong to projects
In my project show, Im trying to count how many invitations have been sent and how many have been accepted.
The first part works fine. For the acceptances, I have an attribute in my project_invitation table called :student_accepted. If that is true, I want to count the record.
<%= #project.project_invitations.size %>
<% if #project.project_invitations.student_accepted == true %>
<%= #project.project_invitations.size %>
<% else %>
'No'
<% end %>
It gives this error:
undefined method `student_accepted' for #<ActiveRecord::Associations::CollectionProxy []>
I have also tried:
<% if project.project_invitations.student_accepted == true %>
<%= project.project_invitations.size %>
It gives this error:
undefined local variable or method `project' for #<#<Class:0x007fc01d9dcbe8>:0x007fc01de04248>
Im struggling to understand how to reference attributes though associated models. I have read several books but they all assume background knowledge. I've had helpful input on related questions (below), but still not grasping the concept.
http://stackoverflow.com/questions/32916133/rails-how-to-show-attribute-of-an-associated-model
http://stackoverflow.com/questions/32898541/rails-how-to-show-attributes-from-a-parent-object
Can anyone see what I've done wrong?
You can find the number of invitations that students have accepted with:
#project.project_invitations.where(student_accepted: true).count
Rails's Active Record Query Interface guide explains how that works.
The reason you received the undefined method 'student_accepted' for #<ActiveRecord::Associations::CollectionProxy []> error is because you were calling student_accepted on a ActiveRecord::Associations::CollectionProxy, which is an object rails creates to define a collection of records.
If you wanted to iterate over that collection you could do:
<% #project.project_invitations.each do |invitation| %>
# here you can call `invitation.student_accepted`
<% end %>
This is necessary because a project has many invitations.
#project.project_invitations gives you an array and Array class does not have the method student_accepted (while each item in the array has this method).
You can use #project.project_invitations.select{|item| item.student_accepted == true}.present? as the condition.
Related
Alright, so I'm very new to rails, so please forgive me if some of these questions seem trivial.
I'm working on a group project in which users view/create the projects that exist, and the projects can display a list of associated users within it. Someone had originally set it up as one-to-many relationship and we had to make it a habtm association.
What I'm asking is how do I make this if statement work that was originally:
<strong><%= project_model.user.name if project_model.user %></strong><br />
</div>
<% if project_model.user == current_user %><br />
Now project_model should have a database/list within project_model.users (a .build was used when creating the project_model so it should at least contain the current_user. Hopefully....)
Something to note: #project_models is defined in the controller, but this is in a 'do' where #project_models.each do |project_models|
Side note: Some of the things one of my group members did is a little outside the scope of the class and so I'm a bit lost on what some of his code is actually doing. If someone could explain what the project_model.user.name if project_model.user contained within the <strong> is actually doing, it would also be really helpful.
Are you asking how to find out if project_model is associated with current_user? If so, try this:
project_model.users.exists?(current_user.id)
Also, this statement:
project_model.user.name if project_model.user
is trying to see if project_model has an existing associated user before attempting to access its name property. If the property_model does not have a user, then property_model.user will return nil. The if statement will treat this as a false value and therefore will not execute the code before it. This avoids a
NoMethodError: undefined method `name' for nil:NilClass
error if project_model.user doesn't exist. However, since you've changed to a habtm association, one ProjectModel can have multiple User's. Perhaps you want to use a project_model.users.each call to display all of the users for the project_model instead?
The way it is written here suggests a Project used to have one user (project.user is singular). Now you have many users working on a same project which should translate to: project.users (notice users is plural) meaning you're dealing with a list of users.
The 2nd if statement checks if you're part of a project before showing you stuff only involved users can know. So you can replace:
<% if project_model.user == current_user %>
# by
<% if project_model.users.map(&:id).includes?(current_user.id) %>
Since we're dealing with a list of users now you also need to iterate through te users you want to display.
So you could replace :
<%= project_model.user.name if project_model.user %>
# by
<%= project_model.users.map(&:name).join(", ") %>
The run down. A person can have many bids, this particular person only has one bid.
In my index action I have #bids = Bid.find_by_person_id(params[:person_id])
in my view I do
<% #bids.each do |bid| %>
<%= bid.bid_amount %>
<% end %>
I am getting NoMethodError: undefined method each' for #<Bid:0x007f988a346f00> when visting the index view for person bids.
Is this because this person only has one bid? I feel thats not the case, but other than that im at a loss..
find_by returns the first item. I think you are looking for
Bid.where(person_id: params[:person_id])
Austio's answer is correct.
However, why are you calling the Bid model directly?...
A person can have many bids
You're obviously constructing data from the person model, so why not call the following:
#person = Person.find params[:person_id]
#bids = #person.bids #-> bids belong to #person
This will build the collection without calling where.
Of course, your method only uses a single db query. But even still, the above is much more intuitive.
--
As an aside, you'll also want to use a conditional before your loop:
<% if #bids.any? %>
<% #bids.each.... %>
<% end %>
Having one bid is fine, but having none will cause the loop to spit out an error. The above resolves that issue.
I have two models - Client & Topic, with a HABTM relationship between them.
I am trying to generate a series of checkboxes of the topics, on the Client form partial.
This is what I am doing:
<% Topic.all.each do |topic| %>
<% checked = #client.topics.include?(topic) %>
<%= f.label(:name, topic.name) %> <%= f.check_box #topics, topic.id %>
<% end %>
This is the error I get:
undefined method `merge' for 1:Fixnum
I know one solution is to use check_box_tag, but that forces me to do the record updating of the associations manually.
So I would rather use the form_helper for the checkbox tag. The docs are a bit confusing to me.
How can I get this to work with f.check_box.
Thanks.
The code confuses me. What #topics contains? If it's a collection of of Topic then why you are directly accessing Topic model in the view? It would be:
#topics.each.do
rather than you
Topic.all.each
Moreover, you are using #topics as collection inside a loop. How check_box will generate checkbox from a collection?
Please look at the following things:
accepts_nested_attributes_for. you will need this to set in Client model in addition to Client has_many Topic association
fields_for Otherwise, rails will not have any idea that you want to update topic model from this same form.
Check this screencasts to get an idea how you can make it work
For whatever reason, the form helper doesn't work with check_box.
So, this is the code that works:
<%= check_box_tag "client[topic_ids][]", topic.id, checked %>
According to other answers for similar questions, the helper f.check_box is model bound and the value supplied to the checkbox is implicit from the model on the form. The issue is, I can't figure out how to get the implicit value of the form_helper to produce the correct tag - i.e. client[topic_ids][], so I have had to resort to check_box_tag.
I am working on an application that involves "follow/unfollow" functionality. Users can follow Objects and Objects can have many Users following them. It's a has_many :through relationship via a Relationships model/controller.
I have the following snippet in the object#show view:
<% if current_user.following?(#object) %>
<%= render 'unfollow' %>
<% else %>
<%= render 'follow' %>
<% end %>
When testing various functionalities in a request spec, it shows undefined method 'following?' for nil:NilClass and fails all of the object#show specs.
The following? method is in the User model and looks like this:
def following?(object)
relationships.find_by_object_id(object.id)
end
The method following? is in the User model (since they are the only ones doing following and unfollowing). I thought you could use methods between objects in Ruby, but perhaps not. If not, how would I go about refactoring this to be able to use that method?
Thanks in advance for any help!
There is no current_user helper in specs. That's why you get nil.
You should stab test user into current_user variable
I recently decided I wanted to list all the users in my Ruby On Rails application - since I couldn't figure out how to list them any other way, I decided to use partials.
I have the following on my administration page (just hooked up to a its own administration controller):
<%= render :partial => User.find(:all) %>
I then have a file called _user.html.erb in my users view folder. This contains the following:
<ul>
<% div_for #user.object_id do %>
<li><%= link_to user.username, user.username %></li>
<% end %>
</ul>
When the application runs and I go to the administration page, I get the following error:
undefined method `id' for 4:Fixnum
It says it's because of this line (which is in the partial file):
<% div_for #user.object_id do %>
I'm unsure why this happens (and have googled for hours to try and find results and only find solutions that don't work for me). I think it's something to do with my usage of the #user instance variable, but I'm not totally sure.
You get that error because div_for expects an active record object as an argument, which it calls the id method on. You pass in a fixnum (the result of #user.object_id), which is not an active record object and does not have an id method.
So pass in #user instead of #user.object_id and it will work.
Also you should use user instead of #user, rails 3 does not set instance variables for partials anymore.
Lose the .object_id part. I seriously can't think why are you using object_id!Do you have a good reason for doing so? Anyway div_for wraps a div around an object, so leave the .object_id part!
instead of object you are using it's column or visa varsa you are using at that time you will get this kind of error.
Example
I am using id instead of user = User.first object.
Try this, it worked for me.
#item.unit_of_measure.name
instead of
#item.unit_of_measure_id.name