Reputation: 3938
I'm trying to get the text "Tags:" to show up only if tags are present, so I did the following in my view:
<% if @tags.present? %>
<%= puts "Tags:"%>
<% end %>
Which doesn't work... I'm a beginner, and have no idea what I'm doing wrong.
Thanks
EDIT:
A tag belongs to an Article.
Tags is defined in my Article model as:
def tag_tokens
self.tags.collect{|t| t.name}.join(", ")
end
def tag_tokens=(tags_delimited)
tags_delimited.split(",").each do |string|
self.article_tags.build(:tag => Tag.find_or_create_by_name(string.strip.downcase))
end
end
I'm trying to make it so that when an article has tags the word "Tags:" shows up before the list of tags, and when an article doesn't have any tags, the word "Tags:" doesn't show up.
Right now <% if @tags.nil %>
just causes "Tags:" to show up on every post.
Upvotes: 0
Views: 1757
Reputation: 10258
Check the answer by sgrif, it contains a lot of good points. To just answer your main question:
In erb (the "language" used for view templates in Rails) you can use <%= ... %>
to interpolate the result of some Ruby code into your view template.
When you are doing:
<%= puts "Tags:" %>
the following happens:
nil
is returned since a call to puts
alsways returns nil
nil
, which shows up as "nothing"To fix it, just use:
<% if @tags.present? %>
<%= "Tags:"%>
<% end %>
or, since you are not doing anything in Ruby, you can just use:
<% if @tags.present? %>
Tags:
<% end %>
Upvotes: 1
Reputation: 3822
You don't use puts in views -- puts causes the text to go to your console. This will fix it:
<% if @tags.present? %>
<%= "Tags:"%>
<% end %>
You also don't need to use .present? by the sound of it. If you only want to see if it's been set, you should use .nil? instead. You can also condense this down to a single line.
<%= "Tags:" unless @tags.nil? %>
UPDATE: It looks like the tag_tokens method is broken for you in both the getter and setter. Your setter isn't actually saving anything by the looks of it (.build returns a new object, you need to save it). Your getter is also referencing tags, instead of article_tags which is what you're trying to save by the looks of it. Changing it to this should work for saving:
self.article_tags.build(:tag => Tag.find_or_create_by_name(string.strip.downcase)).save
This is assuming that you have a line that is something like:
has_many :article_tags
has_many :tags, through: :article_tags
Which I'm assuming you do based on your setter.
I assume this is a many-to-many relationship, but it looks like you're using has_many :through, rather than has_and_belongs_to_many. Is there a reason for this? If you're using has_and_belongs_to_many you should be able to do this:
has_and_belongs_to_many :tags
def tag_tokens=(tags_delimited)
self.tags = []
tags_delimited.split(",").each do |string|
self.tags << Tag.find_or_create_by_name(name: string)
end
end
If you do that, you should not have an ArticleTags model at all, and you should have a table called articles_tags with no primary column, and an article_id and tag_id column.
Update 2:
You're not setting @tags to anything, which is why it's always nil. @tags is a variable, which needs to be set to have a value just like @articles is being set in your controller's index method. Regardless, since this is for an index method, you wouldn't want it to be a single instance variable regardless. You should be accessing your tag_tokens method for that particular instance. app/views/articles/index.html.erb lines 53-55 should be changed to this:
<%= "Tags:" if article.tags.any? %>
Upvotes: 4
Reputation: 3284
What has @tags been defined as? Where do you want to check if it is present?
Do you want if @tags.nil?
Upvotes: 0