Reputation: 5178
I have something like this in my show
action:
def show
@blog = Blog.find(params[:id])
@new_comment = @blog.comments.build
end
Now in the view I do two things:
_form.html.erb
for the Comment
so that the user can add a comment to this blogI am having problems with number 2. The issue is that as I iterate over the associated comments
with this:
<% @blog.comments.each do |comment| %>
It is grabbing that @new_comment
while iterating over the associated blogs. How can I exclude that built-but-not-yet-persisted @new_comment
?
It would be nice if something like @blog.comments.each_with_id
worked, or even @blog.comments.persisted.each
. Ultimately I only want to iterate over the persisted comments
associated to this blog
.
I would prefer not to have to nest a conditional that asks if the comment is persisted?
. I'm hoping there is an iterator out there for my current situation that just grabs the persisted records.
Upvotes: 2
Views: 1018
Reputation: 4820
in your view loop, you can skip if comment.new_record?
<% @blog.comments.each do |comment| %>
<% next if comment.new_record? %>
EDIT per your comment:
if you dont want filter out during the iteration, you can reject new records before iterating. however, i wouldn't recommend this approach, as youre creating an entirely new array of records for little reason. Your performance shoundnt really take a hit assuming blogs dont have thousands of comments, but its still not a great practice.
<% @blog.comments.reject(&:new_record?).each do |comment| %>
if you truly want to separate the logic from the view and controller, you can make another variable entirely dedicated to blog comments, prior to building a new one, so that its not included during the iteration.
# controller
def show
@blog = Blog.find(params[:id])
@current_comments = @blog.comments
@new_comment = @blog.comments.build
end
#view
<% @current_comments.each do |comment| %>
for what its worth, i'd still recommend the first apprach
Upvotes: 2
Reputation: 1691
How about if you create the new comment without using the association to the blog instance? Then it won't show up when you iterate through @blog.comments
.
def show
@blog = Blog.find(params[:id])
@new_comment = Comment.new(blog: @blog)
end
Upvotes: 3
Reputation: 3080
You could add a class method to your Comment
model such as this:
def self.persisted
reject { |comment| comment.new_record? }
end
Then call
@blog.comments.persisted
The downside is that it's not after this you don't have an ActiveRecord::Relation
anymore and might break your scopes chaining. Make sure you're using it last in your ActiveRecord
queries.
Upvotes: 1