I'm having trouble with loading/populating the view with posts after submitting them through AJAX. The form itself is firing off and inserting the posts into the db. To be more clear, I need to load the posts after submission in the container below the post with JQuery slideDown. I have a normal post/shared post/commented post, partial render in the index action as well.
index.html.erb
<div class="col-md-5">
<div class="posts-feed-bg">
<div id="post-index-form">
<%= render 'posts/form' %>
</div>
<div class="post-textarea-bottom-border"></div>
<div class="post-feed-container" id="posts-items">
<% @posts.each do |post| %>
<%= render partial: "posts/#{post.post_type}", locals: {post: post} %>
<% end %>
</div>
</div>
</div>
create.js.erb
<% if @post.save
@post = Post.new
%>
$('#post-index-form').html('<%= escape_javascript(render 'posts/form') %>');
$('#post-text-area').val('');
$('#post-items').html('<%= escape_javascript(render 'posts/post') %>');
$('#post-items').slideDown(350);
<% end %>
_post.html.erb
<div class="post-container">
<%= post.user.username %>
<%= link_to post.title, post %>
<%= post.body %>
</div>
posts_controller.rb
def index
following_ids = current_user.following_users.map(&:id)
following_ids << current_user.id
@posts = Post.where(user_id: following_ids).order('created_at DESC').paginate(page: params[:page])
@users = User.same_background_focus_as(current_user).paginate :page => params[:page], :per_page => 5
@post = Post.new
end
def create
@post = current_user.posts.build(post_params)
respond_to do |format|
if @post.save
format.html { redirect_to @post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: @post }
format.js
else
format.html { render :new }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end
_form.html.erb
<div class="container">
<%= simple_form_for(@post, id: '', multipart: true, remote: true) do |f| %>
<%= f.error_notification %>
<div class="row">
<div class="col-6 emoji-picker-container post-textarea">
<%= f.input :body_text, class: 'form-control', label: false, id: 'post-text-area' %>
</div>
</div>
<div class="row">
<div class="col-md-5">
<%= f.button :submit, class: 'btn btn-outline-success' %>
</div>
</div>
<% end %>
</div>
Server Log After Submitting Form
Started POST "/posts" for 127.0.0.1 at 2017-08-16 13:25:25 -0400
Processing by PostsController#create as JS
Parameters: {"utf8"=>"✓", "post"=>{"body_text"=>"AJAX"}, "commit"=>"Create Post"}
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 4], ["LIMIT", 1]]
(1.0ms) BEGIN
SQL (174.6ms) INSERT INTO "posts" ("body_text", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["body_text", "AJAX"], ["user_id", 4], ["created_at", "2017-08-16 17:25:26.201583"], ["updated_at", "2017-08-16 17:25:26.201583"]]
(0.5ms) COMMIT
Rendering posts/create.js.erb
(1.0ms) BEGIN
(0.0ms) COMMIT
Rendered posts/_form.html.erb (8.0ms) [cache miss]
Rendered posts/_post.html.erb (1273.9ms)
Rendered posts/create.js.erb (1366.9ms)
Completed 500 Internal Server Error in 2282ms (ActiveRecord: 178.1ms)
ActionView::Template::Error (undefined local variable or method `post' for #<#<Class:0x18937128>:0x1a9f6688>
Did you mean? @post
post_url):
2: <div class="media" style="padding-bottom: 2em;">
3: <img class="d-flex align-self-start mr-3 purple-rounded rounded" src="http://via.placeholder.com/60x60">
4: <div class="media-body post-user-name">
5: <h5><%= fa_icon 'user' %> <%= post.user.user_full_name %><%= link_to 'Delete', post_path(post), remote: true, method: :delete, data: {confirm: "You sure?"} if current_user == post.user %> </h5>
6: <p><%= post.body_text %> </p>
7: </div>
8: </div>
app/views/posts/_post.html.erb:5:in `_app_views_posts__post_html_erb__960034244_222460104'
app/views/posts/create.js.erb:9:in `_app_views_posts_create_js_erb__1048995870_223328388'
New Error After making changes
ActionView::Template::Error (undefined method `user_full_name' for nil:NilClass):
2: <div class="media" style="padding-bottom: 2em;">
3: <img class="d-flex align-self-start mr-3 purple-rounded rounded" src="http://via.placeholder.com/60x60">
4: <div class="media-body post-user-name">
5: <h5><%= fa_icon 'user' %> <%= post.user.user_full_name %><%= link_to 'Delete', post_path(post), remote: true, method: :delete, data: {confirm: "You sure?"} if current_user == post.user %> </h5>
6: <p><%= post.body_text %> </p>
7: </div>
8: </div>
app/views/posts/_post.html.erb:5:in `_app_views_posts__post_html_erb__960034244_199162944'
app/views/posts/create.js.erb:9:in `_app_views_posts_create_js_erb__1048995870_199612656'
method for partial view changer post.rb
def post_type
if post_id? && body_text?
"quote_share"
elsif post_id?
"share"
else
"post"
end
end
The problem is you referenced the id
wrongly . You have defined the div
with id
as posts-items
, but in create.js.erb
you are using post-items
which is incorrect, so JS unable to find the selector with post-items
which is the reason for the problem. Changing it to posts-items
should fix your problem.
#create.js.erb
<% if @post.save
@post = Post.new
%>
$('#post-index-form').html('<%= escape_javascript(render 'posts/form') %>');
$('#post-text-area').val('');
$('#posts-items').html('<%= escape_javascript(render 'posts/post') %>');
$('#posts-items').slideDown(350);
<% end %>
Also, this part of the code.
<% if @post.save
@post = Post.new
%>
seems strange. I don't see any reason including it in create.js.erb
unless there is a use. So remove it
#create.js.erb
$('#post-index-form').html('<%= escape_javascript(render 'posts/form') %>');
$('#post-text-area').val('');
$('#posts-items').html('<%= escape_javascript(render 'posts/post') %>');
$('#posts-items').slideDown(350);
Update:
ActionView::Template::Error (undefined local variable or method `post' for #<#<Class:0x18937128>:0x1a9f6688>
Rails unable to find the post
variable defined in _post.html.erb
in this situation. Send it as a local variable in the partial. The final create.js.erb
should like this
#create.js.erb
$('#post-index-form').html('<%= escape_javascript(render 'posts/form') %>');
$('#post-text-area').val('');
$('#posts-items').html('<%= escape_javascript(render 'posts/post', post: @post) %>');
$('#posts-items').slideDown(350);
Also, change @post
to Post.new
in the form
so it won't conflict with @post
in create
action and always create a form for new instance
<%= simple_form_for(Post.new, id: '', multipart: true, remote: true) do |f| %>
ActionView::Template::Error (undefined method `user_full_name' for nil:NilClass)
This error is because that particular post doesn't have an associated user to it, so it errors out in this line <%= post.user.user_full_name %>
To quickly resolve the error, use try
method
<%= post.try(:user).user_full_name %>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.