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
Related
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.
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.
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
I have scoured stack overflow for and answer to my problem but can't find one. So I was hoping that someone else out there has tried what I want to do before.
I have a question model, which has many options. What I want to do is allow the user to copy a list of options into a textarea as a return/new line separated list.
i.e. a list of locations
London
Paris
New York
Singapore
Sydney
And then from the questions controller I want to get each of these items insert them in the options model.
What I can't work out is how I access the textarea element from the controller as there is no object name associated with it.
Any help would be greatly appreciated.
Thanks
Ben
One way to go about it is associate the textarea element with your 'options' attribute, and then write a function in your model to split it into an array.
For example, in your view:
<%= form_for #question do |f| %>
...
<%= f.text_field :options %>
Then in your controller:
def create
#question = Question.new(params[:question])
...
#question.split_options
...
end
In the model, the split_options method could use Ruby's string split functions to return an array, which then gets saved.
I'm developing a simple rails app for my own use for learning purposes and I'm trying to handle 2 models in 1 form. I've followed the example in chapter 13 of Advanced Rails Recipes and have got it working with a few simple modifications for my own purposes.
The 2 models I have are Invoice and InvoicePhoneNumber. Each Invoice can have several InvoicePhoneNumbers. What I want to do is make sure that each invoice has at least 1 phone number associated with it. The example in the book puts a 'remove' link next to each phone number (tasks in the book). I want to make sure that the top-most phone number doesn't have a remove link next to it but I cannot figure out how to do this. The partial template that produces each line of the list of phone numbers in the invoice is as follows;
<div class="invoice_phone_number">
<% new_or_existing = invoice_phone_number.new_record? ? 'new' : 'existing' %>
<% prefix = "invoice[#{new_or_existing}_invoice_phone_number_attributes][]" %>
<% fields_for prefix, invoice_phone_number do |invoice_form| -%>
<%= invoice_form.select :phone_type, %w{ home work mobile fax } %>
<%= invoice_form.text_field :phone_number %>
<%= link_to_function "remove", "$(this).up('.invoice_phone_number').remove()" %>
<% end -%>
</div>
Now, if I could detect when the first phone number is being generated I could place a condition on the link_to_function so it is not executed. This would half solve my problem and would be satisfactory, although it would mean that if I actually wanted to, say, delete the first phone number and keep the second, I would have to do some manual shuffling.
The ideal way to do this is presumably in the browser with javascript but I have no idea how to approach this. I would need to hide the 'remove' link when there was only one and show all 'remove' links when there is more than one. The functionality in the .insert_html method that is being used in the 'add phone number' link doesn't seem adequate for this.
I'm not asking for a step-by-step how-to for this (in fact I'd prefer not to get one - I want to understand this), but does anyone have some suggestions about where to begin with this problem?
There is a counter for partial-collections:
<%= render :partial => "ad", :collection => #advertisements %>
This
will render "advertiser/_ad.erb" and
pass the local variable ad to the
template for display. An iteration
counter will automatically be made
available to the template with a name
of the form partial_name_counter. In
the case of the example above, the
template would be fed ad_counter.
For your problem of detecting whether a row is the first one or not, you could add a local variable when calling the partial:
<%= render :partial => 'mypartial', :locals => {:first => true} %>
As it would be much easier to detect in the main file, whether a row is the first or not I guess.
Instead of detecting whether a phone number is the first, you could also detect whether a phone number is the only one. If not, add remove links next to all numbers otherwise, do not display the remove link. Note that besides showing/hiding the link, you also need to add code, to prevent removing of the last number by (mis)using an URL to directly delete the number instead of using your form.