Limit images show in post to last six - ruby-on-rails

I have with me a set of posts created from a scaffold and images uploaded using paperclip gem. I would like to show on each users profile the last six images from the users last posts and for that I am filtering as such
<% #posts.limit(6).each do |tweet| %>
<% if post.media.present? %>
<%= link_to image_tag(post.media.url(:thumb)), tweet %><br>
<% end %>
<% end %>
In my controller I have the posts arranged as such
#posts = user.posts.order('created_at desc')
My question is. Why is it that when using the above code, NO image is displayed. On upping the count to 9, I get three images displayed, to 12 i get six images displayed and so on

First of all, you should not make the calls to the db/model (with limit) in the views. Call it directly in the controller :
#posts = user.posts.order(created_at: :desc).limit(6)
Then, I would do some debugging to be sure you have the records you want.
Use byebug for instance and call it just after you set you #posts instance variable to see what it contains. Do all the posts contain a media ?

Related

Count the pictures per row in rails

Im made a gallery in rails by creating a div for each image-url in the database in my view. I would like to add a feature, that the user can specify the pictures per row and the number of rows per page on my edit-page. The value will be written to the database and the pagination should than be dynamic using the calculated value (pictures_per_row * rows_per_page).
Problem: Im using images.each method in my view to loop through the pictures and create a div for every image in the gallery. So they are created one after another. Concerning the results are paginated, gives me a specific number for pictures per page. But how do I accomplish something like:
for gallery.image.each do a div, but after 5 divs, continue in new line.
I think the pagination isnt the problem here, because it will paginate whatever the database query delivers.
Any ideas? Thanks in advance.
You could use each_slice. Something like:
<% #gallery.each_slice(5) do |slice| %>
<div class="row">
<% slice.each do |item| %>
<!-- Display images-->
<% end %>
</div>
<% end %>

How to count the amount of times a tag has been used with ActsAsTaggableOn rails

I have a dashboard in my project where I want to show all the tags I have in my project, along with the number of times those tags have been used. For tagging I use the ActsAsTaggableOn gem on my Post model.
I currently have a variable which shows the most used tags in my tagscontroller:
def index
#tags = ActsAsTaggableOn::Tag.all.most_used
end
And I can find the amount of tags a certain post has by going in to rails console and running
post = Post.first
post.tag_counts_on(:tags).count
however I can't figure out how to return the number of times each tag has been used on my Post model.
EDIT:
Thanks to Sam's answer below I managed to find the column in the tags model I wanted to call from (using the debug console). To call the amount of times each tag has been used I did:
#tags = ActsAsTaggableOn::Tag.all
In my tags controller and
<% #tags.each do |tag| %>
<%= tag.name %><%= tag.taggings_count %>
<% end %>
In my view.
According to this and this, you should be able to:
Post.tag_counts
Given :tags is the "context" you used on the Post model.

Rails - showing comments in a different area

Im trying to create a system which allows athletes to respond to their coaches traing plan, to do this i have allowed the coach to create contentsm however i am using a blogging based system to create it... at the moment the page displays like so
CONTENT TITLE
Content info 1...
Content info 2...
Content info 3...
COMMENTS...
comment 1
comment 2
comment 3
.etc
However i want to set it so that there can only be 7 Comments Max per post as well as set out like this per post...
CONTENT TITLE
Content info 1...
comment 1
Content info 2...
comment 2
Content info 3...
comment 3
.etc
I realise this is probably not the best way to do want i want, but it works (just dosnt appear in the place i want it to)
I did do experiments with creating more models, but kept getting errors whenever i tryed to run more than 1 comment system per post. I was wondering if i could have some help in sorting this out, or any methods i could do to make this easier, or even better if the models would work and if i was just doing something wrong?? tell me if this isn't enough information to go off, and ill try provide some more! Thankyou
.
.
EDIT:
The models i have used are
Program - As in the training plan set for the week
Coaches - The coach that is inputing the data to the rider
Riders - To comment on the coaches data with their own data.
I am unsure what files are need exactly so i have included the link to the github page i am pushing to ( https://github.com/effectonedesign/coacheasy1 ), if there is any other info needed, please let me know!
I like what "mind" has said however, i have done everything have said, in my def show (program controller) it is saying there is an error and i keep getting this message undefined method `coaches' for nil:NilClass everything is identical to his but im getting issues, i really do appreciate the help! Thanks
I would probably create 3 models for the above, TrainingPlan, Section (or content, text_block etc.) and Comment.
Then do the following
TrainingPlan has_many :sections
Section belongs_to :training_plan
Section has_one :comment (if you allow only 1 comment per section, otherwise use has_many)
Comment belongs_to :section
Now, to achieve the formatting you wanted do the following in your views:
<% #training_plan.sections.each do |section| %>
<%= section.text %>
<%= section.comment.text %>
<% end %>
If you allow multiple comments:
<% #training_plan.sections.each do |section| %>
<%= section.text %>
<% section.comments.each do |comment| %>
<%= comment.text %>
<% end %>
<% end %>
Form for comments
I haven't tested the following, so you might need to tweak some parts.The training plan controller:
def show
# using includes will query the database 3 times only (once for each table) rather than
# querying it 1 + N + N (in this case 7 sections, 7 comments possibly, so 15 times)
#training_plan = TrainingPlan.includes(:sections, sections: :comment).find(params[:id])
#sections = #training_plan.sections
#sections.each do |section|
# only build a new comment if there is no comment for that section already
section.build_comment unless section.comment
end
end
In your view views/training_plans/show.html.erb
<%= #training_plan.title %> # or whatever
<% #sections.each do |section|
<%= #section.content %>
<% if section.comment %>
<%= section.comment.content %>
<% else %>
<%= render 'comments/form', comment: section.comment %> # or wherever you have the form
<% end %>
<% end %>
views/comments/_form.html.erb
# This might break if you have a separate comment action somewhere which passes an
# instance variable #comment to the form
<%= form_for comment do |f| %>
# normal form stuff
<% end %>
If that all works then on your training plan show page you should see each section, and if it has a comment then that comment will be rendered, otherwise a form will be shown.
Depending on your routes you might need to run rake routes and see where your comment create action is, and then pass that to the form <%= form for comment, url: some_url_helper_here do |comment| %>
If it was me I would create the add comment part through JavaScript, sort of like in this railscast, but since you're new to RoR I've tried to keep it simple.

Cache only the main content in rails

Using Rails 3.1.1 and Heroku.
I believe this should be a fairly easy fix but I cannot find (and easily verify) how to do this. I have a very slow controller (6 sec) Product#show, with lots of N+1 and other things I will have to solve.
The website is a two-column website (main-column and right-column) where the main content from Product#show is shown in one column and daily product are shown in the other, including a "Random Product from the Database".
What I want to do is to let the content in main-column that is created by Product#show be cached (and thus bypass the controller and win 6 seconds). I do, however, want the right column to be dynamic (and loaded for each page request).
If I use caches_page :show it will cache the entire website, including the right-column, which makes me have to expire the cache every day in order to be able to load a new Daily Product. Not a good solution.
If I use cache('product-show' + #product.slug) do it only caches the view (right?) and still have to go through the controller.
So, how can I solve this?
You can achieve this with fragment caching like below:
def show
if !fragment_exist?("main_content")
#products = Product.all
#users_count = User.count
end
#random_products = Product.order("RANDOM()").limit(10)
end
show.html.erb
<!--MAIN CONTENT-->
<% cache("main_content") do %>
<%= #users_count %>
<% #products.each do |product| %>
<%= product.name %>
<% end %>
<% end %>
<!--SIDE CONTENT-->
<% #random_products.each do %>
<%= product.name %>
<% end %>
Use fragment caching, and don't load things in the controller.
If you have a very complex query, let it live in the controller as a scope, and only evaluate it in the view.
If you have a complex process to do so the query must be executed, use a helper method.
If you manage to just load lazy queries in the controller, if the cache is hit none of them will be executed.

Ruby/Rails - Limit the size of a object/hash

I have an object called #events containing about 50 records being pulled from a find condition of my model.
I'm currently displaying the results of the #object in my view like this....
<% for event in #events %>
<p><%= #event.name %></p>
<% end %>
Instead of displaying the entire 50 I would like shrink the set to about 10 records so it displays better on the page.
I cannot use :limit in the find condition since the object is being composed from a variety of loops where after each iteration it adds a few specific records.
So the issue is I have this object #events with 50 records, how can I change the object after its been composed so only the first 10 records remain?
First of all, if you'd like to have pagination, I strongly suggest taking a look at will_paginate
Alternatively, you can do the following to read the first 10 records only.
<% #events.first(10).each do |event| %>
<p><%= event.name %></p>
<% end %>
Or the last 10 records
<% #events.last(10).each do |event| %>
<p><%= event.name %></p>
<% end %>
I didn't test it but you get the point.
are you looking to completely do away with the other 40 or are you just wanting to pull off 10 per page for display purposes. if you are just doing this for display purposes i would look into the will_paginate gem. through its options you could set it so only 10 results per page are shown.
Take a look at will_paginate and kaminari. They both are designed to limit the records retrieved from the database, plus offer helpers for your views to provide the usual number of pages and current page lists.
Will_paginate has been around a while, and is pretty flexible. Kaminari is newer and looks like it has a cleaner interface.

Resources