Rails keeps ignoring an IF statement inside the view - ruby-on-rails

I am writing an application where I want to list blog posts according to date they were created on the main index page. So lets say if I have 10 blog posts that were created today I would want to have smth like this come on the index page of the app..
Today:
POST 1
POST 2
POST 3
... so on
However, I have this...
Today:
POST 1
Today:
POST 2
Today:
POST 3
... so on
The following is my code..
index.html.erb
<% #posts.reverse.each do |post| %>
<% flag = true %>
<% if post.date.day < Time.now.day &&
post.date.day >= (Time.now.day - 1.day) %>
<!-- This IF statement gets ignored -->
<% if flag == true %>
<%= "Today" %>
<% flag = false %>
<br />
<% end %>
<tr>
<td><p>IMAGINE THIS SENTENCE IS ONE POST</p></td>
</tr>
<% end %>
<% end %>
The if statement that gets ignored inside the code acts as a flag, so that it should execute only once per group of posts with the same date. But, Rails seems to completely ignore it for some reason. If someone could help me correct this issue or nudge me in the right direction, your help would be greatly appreciated.

It's not that the if is being ignored, but that on each post the flag is being set to true again.
The first time you set the flag has to be outside of the iteration, like this:
<% flag = true %>
<% #posts.reverse.each do |post| %>
<% if post.date.day < Time.now.day &&
post.date.day >= (Time.now.day - 1.day) %>
<% if flag == true %>
<%= "Today" %>
<% flag = false %>
<br />
<% end %>
<tr>
<td><p>IMAGINE THIS SENTENCE IS ONE POST</p></td>
</tr>
<% end %>
<% end %>

Related

get first 3 occurrence of an array

In my rails app I have below code to print some data from database.
<% #di.each do |d| %>
<% if d["visibility_team"] == 'for_all' %>
//my code goes here
<% end %>
<% end %>
I just want to print first 3 occurrence which fulfill the d["visibility_team"] == 'for_all' condition.
How can I do this?
If you can't get #di as 3 records from DB, how about keeping counter how many ds were printed?
Something like this (feel free to style it the way you want)
<% counter = 0 %>
<% #di.each do |d| %>
<% if d["visibility_team"] == 'for_all' %>
<% counter += 1 %>
<% break if counter == 3 %>
//your code goes here
<% end %>
<% end %>
However it's usually a bad taste to have so much logic in views.

Rails 4/ERB if/else loop gives unexpected ;, expected : error, if I add html or text

I'm trying to create a mobile app in Rails 4/ERB where people can post and comment on others' posts. I'd like to be able to toggle the visibility of comments using jQuery, but whenever I attempt to wrap the each loop in a div tag, or add comments count, I get an error. ('comments/comment' is a partial containing the template for the actual comment)
This works, but shows all the comments (not what I want):
<% if post.comments.count > 0? %>
<% post.comments.order(:created_at).reverse.each do |comment| %>
<%= render 'comments/comment', comment: comment %>
<% end %>
<%:%>
No comments yet.
<% end %>
this gives me an unexpected semicolon error:
<% if post.comments.count > 0? %>
<%= post.comments.count %> Comments.
<% post.comments.order(:created_at).reverse.each do |comment| %>
<%= render 'comments/comment', comment: comment %>
<% end %>
<%:%>
No comments yet.
<% end %>
so does this:
<% if post.comments.count > 0? %>
<div>
<% post.comments.order(:created_at).reverse.each do |comment| %>
<%= render 'comments/comment', comment: comment %>
<% end %>
</div>
<%:%>
No comments yet.
<% end %>
the exact words of the error are syntax error, unexpected ;, expected :
What am I doing wrong, and how can I use HTML within this block without it throwing an error at me? Any help would be much appreciated.
addendum: oddly enough, if I stick the comment count code inside the each loop, it works (but, because it's an each loop, displays it multiple times)
addendum 2: even this gives an error:
<%= render 'comments/form',post: post%></p>
<% if post.comments.count > 0? %>
<!--<%= post.comments.count %> Comments. -->
<% post.comments.order(:created_at).reverse.each do |comment| %>
<%= render 'comments/comment', comment: comment %>
<% end %>
<%:%>
No comments yet.
<% end %>
Try like this
<%= render 'comments/form',post: post%></p>
<% if post.comments.count > 0 %>
<!--<%= post.comments.count %> Comments. -->
<% post.comments.order(:created_at).reverse.each do |comment| %>
<%= render 'comments/comment', comment: comment %>
<% end %>
<%else%>
<!-- No comments yet. --->
<% end %>
remove ? in 2nd line because post.comments.count > 0 this will return true or false,so need to check again.
so,now you can use else condition.
As others have alluded to, the snippet if post.comments.count > 0? implies that you want to use the ruby ternary ?: operator. As its name implies, the ternary ?: operator is composed of 3 parts:
the condition
value if the condition is true
value if the condition is false
Here's an example of its use:
is_even = (num % 2) ? true : false
Note that in this example both the if check (?) and else (:) are included, as is required by the ternary operator. So the issue with your use of ? is that you're using the if check, but not the else check.

How do you implement archive menu for blog system into rails3 app?

When you go to blog page, you will see the archive list on the menu.
In most cases, it shows something like this
'Archive'
2012(78)
-December(1)
-November(5)
-October(10)
...
2011(215)
2010(365)
I'm confident to make blog posting system by using scaffold.
But I have no idea how to make this Archive:(
Anyone come up with good idea to implement this to app easily???
Need your help!!
<h3>Archives </h3>
<% if #posts.to_a.empty? %>
<div class="post">
<p>No articles found...</p>
</div>
<% else %>
<% current_month = 0 %>
<% current_year = 0 %>
<% for article in #posts %>
<% if (article.created_at.year != current_year)
current_year = article.created_at.year
%>
<h3 class="archiveyear"><%= article.created_at.year%></h3>
<% end %>
<% if (article.created_at.month != current_month || article.created_at.year != current_year)
current_month = article.created_at.month
current_year = article.created_at.year
%>
<h4 class="archivemonth"><%= (Date::MONTHNAMES[article.created_at.month]) %></h4>
<% end %>
<div class="archivepost">
<%= link_to article.title, article_path(article), :remote => true %> on <%= article.created_at.strftime('%A')%> - <%= article.created_at.strftime('%d') + "th"%>
</div>
<% end -%>
<%end %>
This may help you. I ve not included the number of counts in this code. Actually m figuring how to do it. If u can let me know.
Also in the controller ive done this.
#posts = Article.order("created_at DESC")
The #posts is an array so the items inside it ll be ordered and then i can fetch the records according to it ordering.
Thanks.

Rails 3: Injecting partials through conditionals

I'm looking to inject a partial/offset of a views pattern based on conditional statements. Don't know how to do this or how complex it may be. To better explain, here's some pseudo examples:
Totals: 1 Post & 3 Jobs
Pattern: 1 Job - 1 Post - 1 Job - 1 Job
A post is inserted between 3 jobs because there is more than 2. How would I do this?
I guess you could do something like this in your view file.
<% if #jobs.count > 2 %>
<% render_post = true %>
<% else %>
<% render_post = false %>
<% end %>
<% #jobs.each do |job| %>
<%= job.some_attribute %>
<% if render_post == true %>
<%= render #post %>
<% render_post = false %>
<% end %>
<% end %>
When render_post is true, rails renders post. When it is false, rails doesn't render post. However, render_post value doesn't appear in the html file.
You need _post.html.erb in the Post's view file.

How to reduce number of hierarchical 'if statements'

I have hierarchical the statements like this
<% #descriptions.each_with_index do |description, i| %>
<% description.tale2.each do |tax_ref| %>
<% if condition %>
<% if condition %>
<% if condition %>
<%= $text_first_describe%> <%= $paren_author_yr %>
<% ref_sp_uniq.each_with_index do |ref, i| %>
<% if ref == tax_ref.ref_wo_brace%>
<% execution %>
<% elsif i == (ref_sp_uniq.size - 1)%>
<%# #ref_desc = "#{#ref_desc_numb}. #{tax_ref.ref_wo_brace}" %>
<% end %>
<% end %>
<% if condition %>
<% execution %>
<% elsif condition %>
<% execution %>
<% elsif taxon_name.emend_author_year %>
<%= print %>
<% else %>
<%= print %>
<% end %>
<% end %>
<% else %>
<% if condition %>
<%= print %>
<% ref_sp_uniq.each_with_index do |ref, i| %>
<% if condition %>
<% execution %>
<% elsif condition %>
<% execution %>
<% end %>
<% end %>
<% if condition %>
<% execution %>
<% elsif condition %>
<% execution %>
<% elsif condition %>
<% execution %>
<% else %>
<% execution %>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>
Kindly suggest me possible way to reduce this kind of junk "if statements".
If your nested IFs are becoming very complex, you might consider describing the entire structure with a state machine and processing it like that. That way you get the documentation of the formal state diagram and your code will be much simpler.
Edit:
Here is a better attempt to describe the process. The nice thing about
this is that once you have your initial state diagram and the code to
process it, adding new states is very easy to do. (Expecially if you
build a little tool to read your diagram and generate your table for
you).
Most people just use these in the context of regular expressions and
leave them alone otherwise, but it is a nice powerful tool to have in
your toolbox. A common example is implementing a full ftp server this
way is trivially easy.
Ok, to my better example, hope this helps.
Consider this IF psuedo code:
if (a < 5)
do_b
do_c
if (a < 3)
do_d
else
do_e
end-if
end-if
The state transition table to process this might look like:
State Transition Action Next state
----- ---------- ------ -----
1 a < 5 2
1 7
2 do_b 3
3 do_c 4
4 a < 3 5
4 6
5 do_d 7
6 do_e 7
7 exit
The code to process it would look like this:
currentState = 1
foreach table entry
if table_state == currentState
&& table_transition is true or blank
call table_action
currentState = table_next_state
Take a look at http://en.wikipedia.org/wiki/State_transition_table for a
more formal description.
first of all I would put this code in a helper, so you get rid of all the tags and you clean the view, then look if you can apply the case statement and latter remember maybe you can include line_of_code if condition or condition ? code_a : code_b.
Hard to do something without conditions (I suppose the condition change each if), why not to address the question to https://codereview.stackexchange.com/
?
Ruby's case syntax would probably be a good starting point for cleaning that up, but like others have mentioned you probably need to rethink whats going on in there. Ultimately you probably want to be moving as much of that logic into the model as you can.
My two cents.

Resources