Rails .all method dumps model in view - ruby-on-rails

How do I stop rails from dumping the entire model in the view in the index method?
Here is my code:
def index
#topics = Topic.all
end
Here is my view
https://41.media.tumblr.com/1bcf55f478094c4ef82cda7676551ffe/tumblr_nsosrw1eRI1r3syg3o1_540.png
(sorry for the bad quality but the dump is at the bottom)

If I'm not mistaken you're adding an '=' in the tag, something like this:
<%= #topics.each do |topic| %>
<%= topic.title %>
<% end %>
when you want this:
<% #topics.each do |topic| %>
<%= topic.title %>
<% end %>

Related

Rails 6 how to decorate application.html.erb

I've got an application.html.erb where I want move calculation of unread user messages into some decorator/helper, basically because it looks like this:
<% if current_user %>
<%= link_to 'Messages', conversations_path %>
<% counter = #conversations.map do |conversation| %>
<% unless conversation.unread_message_count(current_user).zero? %>
<% conversation.unread_message_count(current_user) %>
<% end %>
<% end %>
(<%= counter.sum %>)
I know the basic concept of decorators but I'm wondering if I have ConversationDecorator in app/decorators/conversation_decorator.rb with defined counter method with #conversations.map block there, how to use this decorator inside of application.html.erb ?
Example ConversationDecorator:
class ConversationDecorator < ApplicationDecorator
def unread_counter
#conversations.map do |conversation|
conversation.unread_message_count(current_user) unless conversation.unread_message_count(current_user).zero?
end.sum
end
end

Helper method within each do loop not working

I have a loop that looks like this
<% #user.collections.each do |collection| %>
<h1 class="impact"> <%= collection.name %><br></h1>
<%= collection.stories.count %>
<% end %>
It works perfectly to show the Collections that belongs to a User, and then show how many Stories are in each Collection.
However, I want to use a helper that does this.
in the view
<% #user.collections.each do |collection| %>
<h1 class="impact"> <%= collection.name %><br></h1>
<%= number_of_stories_in_collection %>
<% end %>
in the helper
module CollectionsHelper
def number_of_stories_in_collection
collection.stories.count
end
def render_stories_count
if number_of_stories_in_collection.zero?
'No stories in this collection yet'
else
"#{number_of_stories_in_collection} #{'story'.pluralize(number_of_stories_in_collection)}"
end
end
end
I get an error that says
undefined method `stories' for #<Collection::ActiveRecord_Relation:0x007f510f504af8>
Any help is appreciated, thanks!
The 'collection' variable isn't an instance variable, so the helper can't see it.
Change your view to this:
<% #user.collections.each do |collection| %>
<h1 class="impact"> <%= collection.name %><br></h1>
<%= number_of_stories_in(collection) %>
<% end %>
And your helper method to:
def number_of_stories_in(collection)
collection.stories.count
end
This way you are passing the variable to the helper correctly.
extending #Richard's answer and little bit of optimisation to avoid n+1 queries..
<% #user.collections.includes(:stories).each do |collection| %>
<h1 class="impact"> <%= collection.name %><br></h1>
<%= render_stories_count(collection) %>
<% end %>
helper:
module CollectionsHelper
def number_of_stories_in(collection)
collection.stories.length
end
def render_stories_count(collection)
if (count = number_of_stories_in(collection)).zero?
'No stories in this collection yet'
else
"#{count} #{'story'.pluralize(count)}"
end
end
end

Ruby on rails create a new variable to make an each

i'm new into ruby on rails and i want to assign a variable to make an each like this
<% 3.times do |calendar| %>
<% test = #lessons_calendar %>
<% test.each do |lesson| %>
display html here
<% end %>
<% end %>
The thing is that in my controller i have assigned 3 variables like this #lessons_1 #lessons_2 and #lessons_3 but when i run the code it says undefined method `each' for nil:NilClass, how can i join the number created by calendar to the new variable ? Thanks
Instead of below
<% 3.times do |calendar| %>
<% test = #lessons_calendar %>
<% test.each do |lesson| %>
display html here
<% end %>
<% end %>
Make changes in your controller as well as in view as below
Controller Code
# take new variable
#lessons = []
#lessons << #lessons_1
#lessons << #lessons_2
#lessons << #lessons_3
Now do code in view file as below
<% #lessons.each do |lesson| %>
<% lesson.each do |ls| %>
your code here
<%end%>
<%end%>
Hope this will help you.
<% 3.times do |calender| %>
<%= #lessons_calendar.collect{ |lesson| Write Your Code Here }.join("").html_safe rescue 'No Record' %>
<% end %>
With in the collect iterator you can assign it to instance var if you want to. Thanks

undefined method `value' for #<CategoryItemValue::ActiveRecord_Associations_CollectionProxy:0x007ff9706d24c0>

This is so simple but isnt working. What am I missing?
controlelr
#guide = Guide.friendly.find(params[:guide_id])
#category = #guide.categories.friendly.find params[:id]
#items = #category.category_items
view
<% #items.each do |item| %>
<%= item.category_item_values.value %>
<% end %>
gives the no method error of
undefined method 'value' for #<CategoryItemValue::ActiveRecord_Associations_CollectionProxy:0x007ff9706d24c0>
There is a values column in the category_item_values table so I'm not sure what the problem is.
item.category_item_values is the CollectionProxy instance (one might think of it as of an kinda array.)
Each category_item has [likely, you did not provide sufficiently enough info to guess more precisely] many values. If the assumption above is correct, here you go:
<% #items.each do |item| %>
<% item.category_item_values.each do |value| %>
<%= value %> # or maybe (depending on your model) <%= value.value %>
<% end %>
<% end %>
You will have to loop over each of the category_item_values to get the result as this suggests <CategoryItemValue::ActiveRecord_Associations_CollectionProxy:0x007ff9706d24c0> that your category_item_value is a association.
So you could do something like
<% item.category_item_values.each do |category_item_value| %>
<%= category_item_value.value %>
<% end %>

Am I supposed to do this in helper? or does this make slower?

In this case which pattern will be faster?
Obviously Pattern1 with helper looks much more sophisticated and looks clean.
But it send SQL every time when user_link method is called.
Here it calls up to 100times at one page loading.
Which way would be better for benchmark performance?
Pattern1. With helper
application_helper
def user_link(username)
link_to User.find_by_username(username).user_profile.nickname, show_user_path(username)
end
view
<% #topics.order("updated_at DESC").limit(100).each do |topic| %>
<%= user_link(topic.comment_threads.order("id").last.user.username) if topic.comment_threads.present? %>
<% end %>
Pattern2. Without helper. Just only view
<% #topics.order("updated_at DESC").limit(100).each do |topic| %>
<%= link_to(topic.comment_threads.order("id").last.user.nickname, show_user_path(topic.comment_threads.order("id").last.user.username) ) if topic.comment_threads.present? %>
<% end %>
try
# Topics model
#via scope
scope :get_topic_list, lambda do
order("updated_at DESC").joins(:comment_threads => :user).limit(100)
end
#via method
def self.get_topic_list
Topic.order("updated_at DESC").joins(:comment_threads => :user).limit(100)
end
# in your controller or move to model itself (recommened)
#topics = Topic.get_topic_list
# in you view
<% #topics.each do |topic| %>
<%= link_to(topic.comment_threads.order("id").last.user.nickname, show_user_path(topic.comment_threads.order("id").last.user.username) ) if topic.comment_threads.present? %>
<% end %>

Resources