In my show view I have this div:
<% if #question.answers.any? %>
<div class="parent">
<%= render :partial => #question.answers %>
</div>
<% else %>
<p class="hideAns">No answers yet. Be the first first to answer!</p>
<% end %>
As shown from the code above, I am displaying a paragraph if the question has no answers. The problem that I am facing is checking if the question has answers again with ajax.
In my create.js.erb file, I have this block of code that hides the paragraph:
$("#answers").append("<%= j render #answer %>");
tinyMCE.activeEditor.setContent('');
$(".hideAns").css("cssText", "display: none;");
In my delete.js.erb file, (This is where I am getting the Internal server error.) I have this block of code that checks whether the question has any answers or not:
$("#answer_<%= #answer.id %>").remove();
<% if #questions.answers.any? %>
console.log("has answers");
<% else %>
$(".hideAns").css("cssText", "display: block;");
<% end %>
Why is it not working? Am I not allowed to put an if statement inside a .js.erb file?
EDIT
Server log:
ActionView::Template::Error (undefined method `answers' for nil:NilClass):
1: $("#answer_<%= #answer.id %>").remove();
2:
3: <% if #question.answers.any? %>
4: console.log("has answers");
5: <% else %>
6: $(".hideAns").css("cssText", "display: block;");
7: <% end %>
Answer was to simply define the instance variable in the destroy method.
The fix:
def destroy
#question = Question.find(params[:question_id])
#answer.destroy
respond_to do |format|
format.html { redirect_to :back }
format.js
end
end
Related
I realize there are dozens of similar questions here on this topic, I have looked through many of them and tried to duplicate the solutions and nothing has worked for me.
I have a list of tasks displayed in the index view as a partial, when the user adds a task I would like list to show the newest task (as well as all the others already there).
Here is the create controller:
def create
#task = current_user.tasks.build(task_params)
if #task.save
flash[:success] = "Task added"
respond_to do |format|
format.js
end
else
flash[:error] = "Task not added"
render 'new'
end
The _new partial:
<%= form_for(#task, method: :post, remote: true) do |f| %>
<%= f.label :comments %>
<%= f.text_field :comments, id: "task-comments" %>
<%= f.submit "Insert" %>
<% end %>
Index.html.erb
<div id="new-task-form">
<%= render 'new' %>
</div>
<div id="current-tasks">
<%= render partial: 'show_list', locals: {tasks: #tasks} %>
</div>
create.js.erb
console.log("create.js.erb called");
document.getElementById("task-comments").value = "";
document.getElementById("current-tasks").html('<%= j(render partial: "show_list") %>');
I have been able to get the console to log the message and even been able to clear the input box but the partial does not render, I have tried this in a few different ways and the script always seems to stop executing when it gets to the escape javascript line.
There are no JS errors, as stated above, the console logs the message when the "submit" button is pressed. There is a warning [Violation] Forced reflow while executing JavaScript took 114ms but I don't think that is relevant to this issue.
Here is the partial that I am trying to render _show_list.html.erb
<% unless #tasks.nil? %>
<ul>
<% tasks.each do |tsk| %>
<li><%= tsk.comments %></li>
<% end %>
</ul>
<% end %>
def create
#task = current_user.tasks.build(task_params)
if #task.save
flash[:success] = "Task added"
#respond_to do |format|
#format.js
#end
else
flash[:error] = "Task not added"
render 'new'
end
end
It's always good practice to use local variable in partial
1) => Index.html.erb
<div id="new-task-form">
<%= render 'new' %>
</div>
<div id="current-tasks">
<%= render partial: 'show_list', locals: {tasks: #tasks} %>
</div>
2) => If you are using jquery (create.js.erb)
console.log("create.js.erb called");
$("#task-comments").val('');
$("#current-tasks").html('<%= j render "show_list", tasks: #tasks) %>');
3) => _show_list.html.erb(Use tasks instead of #tasks)
<% unless tasks.blank? %>
<ul>
<% tasks.each do |tsk| %>
<li><%= tsk.comments %></li>
<% end %>
</ul>
<% end %>
ok you have some problem here with your validation on the show_list partial.
you have this line
<% unless #tasks.nil? %>
try to use something more readable like
<% if #tasks.present? %>
and on your controller create action, you don't fill the #tasks variable, so that's the problem in reality, add on you controller the load for all the tasks after saving the new one.
if #task.save
#tasks = Task.all
flash[:success] = "Task added"
and that will make it work, but I recommend to load just the created one and add just one column to the table and not update the complete list again if you have all the others on the client already.
I'm new to programming and have been learning Ruby on Rails for about 6 weeks. I've added commenting functionality to my app, and while comments are being displayed properly, so is everything else in the (sqlite3) database associated with the comment - created_at, updated_at, comment_id, post_id.
The partial that displays comments has the following code:
<%= form_for [post, comment] do |f| %>
<p><%= #comments.each do |comment| %></p>
<small>
<p><%= comment.body %></p>
</small>
<% end %>
<% end %>
As you can see, I'm only trying to display the comment body, but I'm displaying everything.
Here is the create method from the comments controller:
def create
#post = Post.find(params[:post_id])
#comment = current_user.comments.build(params_comment)
#comment.post = #post
authorize #comment
if #comment.save
flash[:notice] = "Comment was created"
redirect_to [#post.topic, #post]
else
flash[:error] = "Comment failed to save"
redirect_to [#post.topic, #post]
end
end
end
I'm not sure why everyting is displaying if I'm only calling .body on comment. I've researched this problem but haven't found anything. Any help would be appreciated.
Here is the fix :-
<%= form_for [post, comment] do |f| %>
<!-- Here I removed `=` from `<%` %> -->
<p><% #comments.each do |comment| %></p>
<small>
<p><%= comment.body %></p>
</small>
<% end %>
<% end %>
#each returns the collection when the block is finished with full iteration. Now, you used <%= ..%>, which then printing the return value of #each. But if <%..%>, it wouldn't print although the #comments.each still returning the #comments collection.
I have almost done! but I have an issue, in my Controller file have this:
def show
#user = User.find(params[:id])
#posts = #user.posts.paginate(page: params[:page])
end
Then I have this piece of code in my file show.html.erb:
<div class="span8">
<%= render 'follow_form' if signed_in? %>
<% if #user.posts.any? %>
<h3>Microposts (<%= #user.posts.count %>)</h3>
<div id='posts'>
<div class='page'>
<ol class="microposts">
<%= render #posts %>
</ol>
</div>
</div>
<% end %>
</div>
At the bottom of this file, I have a Javascript code that I have taken from the tutorial: https://github.com/amatsuda/kaminari/wiki/How-To:-Create-Infinite-Scrolling-with-jQuery
In the same folder I have the file index.js.erb with:
$("#articles").append("<div class='page'><%= escape_javascript(render(#users)) %></div>");
$("#posts").append("<div class='page'><%= escape_javascript(render(#posts)) %></div>");
In a partial _posts.html.erb have this:
<div class='article'>
<%= image_tag(user.picture_url, :width => 50) %>
<%= link_to user.name, user %>
<% if current_user.admin? && !current_user?(user) %>
| <%= link_to "delete", user, method: :delete,
data: { confirm: "You sure?" } %>
<% end %>
</div>
The first one already works in my file index.html.erb, the problem is with the second piece of code, when I try to render the partial at #post, It brings the follow log:
**
'nil' is not an ActiveModel-compatible object that returns a valid partial path.
Extracted source (around line #2):
1: $("#articles").append("<div class='page'><%= escape_javascript(render(#users)) %></div>");
2: $("#posts").append("<div class='page'><%= escape_javascript(render(#posts)) %></div>");
**
How can I render that partial?
Thanks a lot :D
I usually use the .js.erb template to render the partial into a var then set it on the page using JS. Be sure to escape_javascript the template content otherwise you will get JS errors.
<% template_html = render :partial => '_feed_item.html.erb' %>
<%="$('div#content').html('#{escape_javascript(template_html)}</div>');" %>
I think the above should work in erb. I use HAML so mine looks like:
-template_html = render :partial => 'partial_template'
!="$('div#content').html('#{escape_javascript(template_html)');"
Cheers.
Based on your In script I'm calling to /users?page=, and I was wondering that It may calls the line, you must make sure that your controller is populating the #posts variable if your view is using this. Can you show the controller method users?
I cannot figure out why my rails views are not recognizing flash[:notice] or flash[:error]. I keep getting the following error regarding the partial view being rendered. The specific error is:
ActionView::Template::Error (You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[]):
In my controller I have
def index
#organisms = Organism.all
flash[:error] = "test"
flash[:notice] = "test"
respond_to do |format|
format.html
format.json { render :json => #organisms }
end
end
In my index.html.erb file I render out a partial through:
<%= render "shared/flash" %>
The partial has the following code.
<div id="flashes">
<% if flash[:notice] %>
<p id="flash_notice" class="messages notice"><%= flash[:notice] %></p>
<%= javascript_tag "$('#flash_notice').effect('highlight',{},1000);" %>
<% end %>
<% if flash[:error] || flash[:errors] %>
<p id="flash_errors" class="messages errors"><%= flash[:error] || flash[:errors] %></p>
<%= javascript_tag "$('#flash_errors').effect('highlight',{},1000);" %>
<% end %>
<% flash[:error] = flash[:errors] = flash[:notice] = nil %>
</div>
However, if instead of rendering the partial I throw in <%= notice %> it renders out the notice.
If I take the partial code and stick it in the top of the index.html.erb file it renders correctly. Thus, I assume that I am rendering the partial view wrongly?
Any help is much appreciated. Thanks!
Don't name your partial flash. Ruby on Rails creates a local variable with the same name as the partial. In your case, a flash local variable is being created.
Rename your partial to something other than flash and it should work.
Also, you shouldn't need to set flash to nil at the bottom of your partial. Let Rails take care of that for you.
You have to pass the flash to the partial:
<%= render 'shared/flash', flash: flash %>
Or a bit longer:
<%= render partial: 'shared/flash', locals: { flash: flash } %>
So for some reason my code seems to have a mind of its own and will work at some points and then other times will throw an error saying undefined name method when trying to run this code in the view
<%= div_for comment do %>
<p>
<big><%= h(comment.body) %> - <%= link_to comment.user.name, comment.user %> </big><br />
Posted <%= time_ago_in_words(comment.created_at) %> ago
</p>
<% end %>
The code for my comments controller looks like this
def create
#post = Post.find(params[:post_id])
#comment = #post.comments.build(params[:comment])
#comment.user_id = current_user.id
#comment.save
respond_to do |format|
format.html { redirect_to #post}
format.js
format.json { render :json => #comments }
end
end
Like I said sometimes this code works fine and sometimes it doesn't. I'm not sure whats causing the problem, whats even more weird is that in my localhost its working fine but when I push the code to my domain it doesn't work. Before you say it may be a domain rails version mismatch you should know this problem has occurred on my localhost as well before and then resolved itself magically without me changing any code. If anyone could help me it would be greatly appreciated.
Edit: Here is the error log you requested
Completed 500 Internal Server Error in 286ms
ActionView::Template::Error (undefined method `name' for nil:NilClass):
1: <%= div_for comment do %>
2: <p>
3: <big><%= h(comment.body) %> - <%= link_to comment.user.name, comment.user.name %></big><br />
4: Posted <%= time_ago_in_words(comment.created_at) %> ago
5: </p>
6: <% end %>
app/views/comments/_comment.html.erb:3:in `block in _app_views_comments__comment_html_erb___3516162043769402279_2170426440__2165839557434581766'
app/views/comments/_comment.html.erb:1:in `_app_views_comments__comment_html_erb___3516162043769402279_2170426440__2165839557434581766 '
app/views/posts/show.html.erb:14:in `_app_views_posts_show_html_erb__667623582898069867_2171134300_136023206927572946'
app/controllers/posts_controller.rb:23:in `show'
You may checkout the value of comment.user when the error occurs. It seems that comment.user is not an object User as you expect. Checkout your database, maybe some comments are not associated with users or associated with non-existant users.
You can try to debug like this when you'll have the error again:
<% comments.each do |comment| %>
<%= debug comment %> // Or comment.user
<% end %>