Rails .count action with specific :id - ruby-on-rails

We have Questions and Answers, and every Question has_many :answers and those answers belongs_to :questions.
I want to display the CURRENT count of answers on the CURRENT Question.
i tried in my Answers_Controller :
def show
#question = Question.find(params[:question_id])
#answers_count = #question.answers.count
end
and then called on my view <%= #answers_count %>.
But i think i'm missing something here, because nothing is Displayed.

I found out that i don't need to call those in my Controller, i can instead just call
<%= #question.answers.count %>

Try changing:
#answers_count = Question.answers.count
to:
#answers_count = #question.answers.count
You are finding a particular question in your first line and assigning it to #question, but then are not querying that particular question (using Question instead of #question)
Also, look into the differences between count and size to make sure you are not querying the DB more than you have to -- this is a good discussion: ActiveRecord: size vs count

Related

Rails adds extra empty element to end of ordered list when iterating through array

I have a list of 4 comments I want to iterate into an ordered list to create 4 lines of comments.
My ERB partial:
<ol>
<% #post.comments.each do |c| %>
<li><%= c.body %></li>
<% end %>
</ol>
However, when it is being rendered on the page it looks as follows:
1. Foo
2. Bar
3. Baz
4. Foobar
5.
It seems to be adding an extra empty element at the end of the loop cycle.
What seems to be the issue with how I'm iterating through the array?
Please check how many comments you have associated with the post like below,
#post.comments.count
There will be 5 records. Delete the last one and add validation in comment model by below,
validates_presence_of :body
That should keep it from producing blank records. Let me know if that is not the case.
After some digging, I found out my answer.
I failed to mention in my question that I also had a form_for a new comment on the same page that listed comments.
On my Post controller, I had it set up as #comment = #post.comments.new on that action. Which, in turn created an empty, unsaved comment on that view for #post. So, on that action I changed it to a generic #comment = Comment.new and then manually passed in the ids that I needed to make the association in the end. I don't know if that's the "best" way, but it is the way it worked for me.

Rails .count and .each give a different number of results

I'm working with a simple rails app locally for my own learning.
In my view, I have the following code;
Reviews (<%= #reviews.count %>)
<% if #reviews.any? %>
<% #reviews.each do |review| %>
This is one review <br />
<% end %>
<% end %>
Despite this seeming quite simple, the output is as follows;
Reviews (2)
This is one review
This is one review
This is one review
This seems to contradict itself on what should be a very simple pair of operations on the same array.
For reference, the array is built in the controller, using the following code;
class PlacesController < ApplicationController
def show
#place = Place.find(params[:id])
#reviews = #place.reviews
#title = #place.name
end
end
What might be the problem?
I would venture to answer: try to change code inside controller to:
#reviews = #place.reviews.uniq
And check the result.
Seems to fix it. Any idea why? – Matthew Higgins
SQL Inner joins took a place here :)
They produces a duplicate entities. You can ensure, by modifying your controller:
def show
#place = Place.find(params[:id])
sql_query = #place.reviews.to_sql
render text: sql_query
end
You'll see sql query in browser. Then execute this query in you database manager, and you'll see the duplicated results set.
I don't like answering my own question, but I think it's important to explain what I found out incase anyone else ends up in the same place.
As Vitalyp suggested, replacing #reviews = #place.reviews.uniq with #reviews = #place.reviews.uniq produced the correct number of rows, but I was struggling to work out why, when opening the table clearly showed there were only two records.
It turned out there was another model, one I had previously tried using, to create a many-to-many association, which was confusing matters. It would appear that as I hadn't fully removed it after deciding not to use it, and when I completely destroyed the model, it's tables and anything that referenced it, things went back to normal.
It would appear that review 1 was associated with the place twice, once directly and once via the old many-to-many table, so it appeared twice.
It doesn't make a huge amount of sense when I had deleted the has_many:, but I guess it is a peculiarity of how Rails works.

rails 3 displaying a where

using the below code i can search a table using the question id and position where position will be the biggest number
<%= #question = Question.where('question_group_id' =>params[:question_group_id]).order(params[:position]).last>
however i get
#<Question:0x3fe85c0>
how do i display it with the actual position number
thank you
I know it may be a repost but i found two or three answers on these boards pertaining to different questions where the user got a similar result but they didnt help
Do this part in your controller:
#question = Question.where('question_group_id' => params[:question_group_id]).order(params[:position]).last
And you can use this part in your view to show all the attributes
<%= #question.inspect %>
Or to show one attribute you can use
<%= #question.position %>
Note that when you put it in the <%= %> tag it automatically will perform a to_s, so while you might see something more verbose printed in your console when you check what #question is, to get what will actually display, try #question.to_s
(also note that #question will not be available in the console, but you can copy and paste the relevant code)
Question.
where('question_group_id' => params[:question_group_id]).
order(params[:position]).
last
returns an instance of Question. That being said if you want the position you must get the attribute. So all you need is to call .position after .last

How Do I Use collection_select Command for Multiple Values to Update A Second Model?

I am developing a Media Library (model MediaLibrary) where I want to be able to assign multiple topics to each item.
I have created a model MediaTopic that will contain the id of the media library item and the topic id from the Topic model.
The MediaLibrary model has_many :media_topics. The MediaTopic model belongs_to :media_library.
Here is my collection_select statement.
<%= f.label :topic, "Main Topic" %><%= collection_select(:media_library, :topic_id, Topic.order('name'), :id, :name, {prompt: true}, {multiple: true}) %>
I currently have :topic_id in the MediaLibrary model. I got an obvious error where it is trying to write an array of ids into a single integer value. I want to keep the current command without the multiple: true parameter and add a new command changing :topic_id to something that can hold more than one value then create the MediaTopic rows. When I change :topic_id in the collection_select statement above I get an undefined method error. My goal is to get the new logic working before I drop the column.
How do I capture the array that the above collection_select statement is creating? Once I figure that out I can loop through the array and build my MediaTopic rows. I thought about maybe using fields_for. However after seeing that I already have an array that the collection_select is creating I would like to just access the array and loop through it.
I have seen several solutions for more difficult situations on Stack Overflow. I have tried piecing them together but to no avail. I hope that since I know I am creating an array of IDs that somehow I can assign them to something in the collection_select statement.
Any help would be appreciated. I'm obviously missing something that I will probably scream DUH if someone gives me the answer. I'm just not seeing it at the moment.
UPDATE 2/18/2013 7:10 am
Here is the code that I ended up using in my view:
<%= fields_for :media_topics do |media_topic| %>
<%= media_topic.label :topic, "Topics" %><%= media_topic.collection_select(:topic_id, Topic.order('name'), :id, :name, {}, {multiple: true}) %>
<% end %>
Here is the code that I ended up using in my controller (create):
#media_library = MediaLibrary.new(params[:media_library])
#media_topics = params[:media_topics]
if #media_library.save
if #media_topics
#topic_ids = #media_topics["topic_id"]
#topic_ids.each do |topic|
if topic.blank?
else
#media_topic = MediaTopic.new
#media_topic.media_library_id = #media_library.id
#media_topic.topic_id = topic.to_i
#media_topic.save
end
end
end
end
Here is the code that I ended up using in my controller (update):
#media_library = MediaLibrary.update_attributes(params[:media_library])
#media_topics = params[:media_topics]
if #media_library.save
if #media_topics
MediaTopic.where("media_library_id = ?", params[:id]).destroy_all
#topic_ids = #media_topics["topic_id"]
#topic_ids.each do |topic|
if topic.blank?
else
#media_topic = MediaTopic.new
#media_topic.media_library_id = #media_library.id
#media_topic.topic_id = topic.to_i
#media_topic.save
end
end
end
end
In my loops I checked for the array item for blank because the 1st entry of the array was blank. I assume it has something to do with the prompt feature. Anyway my code is working well. I have duplicated it with another model and will probably do this for two more. Next trick is to add this to my already complicated search engine logic.
Since I originally wrote this question I have rewritten my application in Rails 4. I was able to develop a solution to this using has_many through and replacing my fields_for statement with a straight collection_select statement. I ended up answering my own question. The answer on the link below details how I finally solved this issue.
Rails 4 - Using collection_select to get an array of ids for an Intermediate Table with Nested Attributes

Issues with Relationships

You can take a look at the app I'm referring to at:
http://github.com/585connor/QA
So, I've built this question & answer app... kind of. I can get the
answers to be listed on their respective questions but I cannot figure
out how to get the user info to be displayed on those questions/answers.
For example I'd like to put the username next to each answer and the
username next to each question. Also, when viewing the show action of
the users controller, I'd like to be able to see a list of that
particular user's questions and answers.
There are three tables: questions, answers and users. Can you take a
look at the github repository and try to point me in the right direction
for what steps I should take/concepts I should learn in order to achieve
what I'm trying to do?
Becase you have a
belongs_to :user
in your question and answer model, you can access the associated user-model by calling .user on a question or answer object:
# controller
#question = Question.find :first
# view
<%= #question.user.name %>
Accessing the user's questions and answers is similar:
# controller
#user = User.find :first
# view
<% #user.questions.each do |question| %>
<%= question.title %>
<% end %>

Resources