Rails rendering comments both ascending and non-blocked - ruby-on-rails

It is straightforward enough to display only the comments by people the user hasn't blocked:
<% post.comments.each do |comment| %>
<% unless user.blocking?(comment.user) %>
<%= render comment %>
<% end %>
<% end %>
It is also straightforward to display the comments in ascending order (the ascending scope is defined):
<% if post.comments.any? %>
<%= render post.comments.ascending %>
<% end %>
But how do you do both of these things at once in a succinct railsy way?

Just order the comments before iterating over them with each:
<% post.comments.ascending.each do |comment| %>
<% unless user.blocking?(comment.user) %>
<%= render comment %>
<% end %>
<% end %>
You can also combine the unless with your output:
<% post.comments.ascending.each do |comment| %>
<%= render comment unless user.blocking?(comment.user) %>
<% end %>
By the way, ascending isn't documented anywhere - in what context are you using it? Do you have a scope defined for it?

Related

How can I show all models in one index page and order them by "created_at DESC"?

I have a Posts Model, and a Projects Model. I want to render both of these on one index page and order them by created_at DESC. How can I do this? Thanks in advance...
Separately?
<% Post.order('created_at DESC').each do |post| %>
#do things
<% end %>
<% Project.order('created_at DESC').each do |project| %>
#do things
<% end %>
Together?
<% (Post.all + Project.all).sort_by{|item| -item.created_at}.each do |item| %>
<% if item.is_a? Post %>
<%= render 'post_partial', post: item %>
<% elsif item.is_a? Project %>
<%= render 'project_partial', project: item %>
<% end %>
<% end %>
Then create a partial for both objects, and use your attributes as needed!

Looping through different types of posts

I'm building a feed of images, videos, and text-posts using the same model.
For an image post I have an image column, for text a body field, and for videos a url. I have separate partials for each type of post. Right now I'm looping through the posts like this:
<% #posts.each do |post| %>
<% if post.image.present? %>
<%= render 'image_post' %>
<% elsif post.body.present? %>
<%= render 'text_post' %>
<% else %>
<%= render 'video_post' %>
<% end %>
<% end %>
It starts to get messy if I add any more types of posts. Is there a better way to do this?
Also, say I wanted to loop through just the video-posts. Can I loop though posts only with video_url present instead of doing this?
<% #posts.each do |post| %>
<% if post.video_url.present? %>
<%= render 'video_post' %>
<% end %>
<% end %>
you can add a mothod to you model to return the type of post
def type
return "image" if image.present?
return "text" if body.present?
return "video"
end
In your view
<% #posts.each do |post| %>
<%= render "#{post.type}_post" %>
<% end %>

Rails loop in html erb

How can I simplify the following lines:
<% if #campaign.previous_campaign.present? %>
<%= #campaign.previous_campaign.product_name %>
<% if #campaign.previous_campaign.previous_campaign.present? %>
<%= #campaign.previous_campaign.previous_campaign.product_name %>
<% end %>
<% end %>
I need to keep adding ".previous_campaign" until it is not present. So the next one in the above code would be:
<%= #campaign.previous_campaign.previous_campaign.previous_campaign.product_name %>
etc etc.
Something like this:
<% campaign = #campaign %>
<% while campaign.previous_campaign.present? %>
<% campaign = campaign.previous_campaign %>
<%= campaign.product_name %>
<% end %>
The code may need some debugging, but I guess the idea is clear
You could do something like this:
<% for c in #campaign do %>
<% if c.previous_campaign.present? %>
<%= c.previous_campaign.product_name %>
<% end %>
<% end %>

Rails element if first time appearance

I have a model Post with :mark, :text
I have a list with my post
<% #posts.each do |p| %>
# todo
<% if p.mark? %>
<%= p.mark %> <%= sweet_thing(p.text) %>
<% else %>
<%= sweet_thing(p.text) %>
<% end %>
<% end %>
I need to show p.mark name instead #todo where p.mark first time appearance.
Final txt example:
Audi
Audi, text-text-text-text.
Audi, text-text-text-text.
Audi, text-text-text-text.
Ford
Ford, text-text-text-text.
Ford, text-text-text-text.
Ford, text-text-text-text.
Ford, text-text-text-text.
UPDATE
My txt render in controller
def txt_receiver
#posts = Post.where("created_at >= ?", 7.days.ago.utc).find(:all, order: "mark, LOWER(post)")
render "txt_for_newspapper", formats: ["text"]
end
An obvious solution is to keep track of seen marks.
<% seen_marks = {} %>
<% #posts.each do |p| %>
<% unless seen_marks[p.mark] %>
<%= p.mark %>
<% seen_marks[p.mark] = true %>
<% end %>
# rest of your code
<% end %>
A better solution (I think) involves grouping posts by their mark and then outputting in groups. But I'm not sure whether it will match your logic regarding missing marks.
<% #posts.group_by(&:mark).each do |mark, posts| %>
<%= mark %>
<% posts.each do |p| %>
<%= p.mark if mark %> <%= sweet_thing(p.text) %>
<% end %>
<% end %>

how can i compare the selected values with the existing one in rails

I have a view like this,
<% count = 1 %>
<% for voting in #voting %>
<% if voting.question_id.eql?(count) %>
<%= radio_button( count, voting.vote_count, :radio_id => voting.nominees ) %>
<%= voting.nominees %>
<% end %>
<% if voting.nominees.eql?(radio_id) %>
<% voting.update_attribute('vote_count', voting.vote_count+1 ) %>
<% end %>
<% count += 1 %>
<% end %>
how can i compare the selected nominees with the existing one.
any help on this would be very useful...
Some models and associations would be handy here. I suspect options_from_collection_for_select will be your best friend. Also look at increment.

Resources