I want to load more comments but it is not working as I wanted, I've checked the console, it is showing no change, here is the code for my _post.html.erb:
<div class="posts-wrapper">
<div class="post">
<div class="post-head">
<div class="thumb-img"></div>
<div class="user-name">
<%= post.user.name %>
<span class="badge"><%= time_ago_in_words(post.created_at) %></span>
</div>
</div>
<div class="image center-block">
<%= link_to (image_tag post.image.url(:medium), class:'img-responsive'), post_path(post) %>
</div>
<div class="post-bottom">
<div class="caption">
<div class="user-name">
<%= post.user.name %>
</div>
<span class="label label-info">caption:</span><span style="color: black"><%= post.caption %></span>
</div>
<div class="comments" id="comments_<%= post.id %>">
<% if post.comments.any? %>
<div class="paginator" id="comments-paginator-<%= post.id %>">
<% unless post.comments.count <= 4 %>
<%= link_to "view all #{post.comments.count} comments", post_comments_path(post), remote: true, class: 'more-comments', data: {post_id: "#{post.id}", type: "html"} %>
<% end %>
</div>
<%= render post.comments.last(4), post: post %>
<% end %>
</div>
</div>
<div class="comment-like-form row">
<div class="like-button col-sm-1">
<span class="glyphicon glyphicon-heart-empty"></span>
</div>
<div class="comment-form col-sm-11">
<%= form_for([post, post.comments.build], remote: true) do |f| %>
<%= f.text_field :content, placeholder: 'Add a comment...',class: "form-control comment_content", id: "comment_content_#{post.id}"%>
<% end %>
</div>
</div>
</div>
</div>
and here is _comment.html.erb
<div class="comment">
<div class="user-name">
<% if comment.user %>
<%= comment.user.name %>
<% end %>
</div>
<div class="comment-content">
<%= comment.content %>
<span class="label label-warning"><%= time_ago_in_words(comment.created_at)%></span>
</div>
<% if comment.user == current_user %>
<%= link_to post_comment_path(post, comment),id:"post#{post.id}comment#{comment.id}", method: :delete, data: { confirm: "Are you sure?" },remote: true do %>
<span class="glyphicon glyphicon-trash"></span>
<% end %>
<% end %>
</div>
and here is comment_controller
class CommentsController < ApplicationController
before_action :set_post
def index
#comments = #post.comments.order("created_at ASC")
respond_to do |format|
format.html { render :layout => !request.xhr? }
end
end
def create
#comment = #post.comments.build(comment_params)
#comment.user_id = current_user.id
if #comment.save
respond_to do |format|
format.html { redirect_to posts_path }
format.js
end
else
flash[:alert] = "Check the comment form, something went wrong."
render posts_path
end
end
def destroy
#comment = #post.comments.find(params[:id])
#comment.destroy
respond_to do |format|
format.html { redirect_to posts_path }
format.js
end
# flash[:success] = "Comment deleted :("
# redirect_to posts_path
end
private
def comment_params
params.require(:comment).permit(:content)
end
def set_post
#post = Post.find(params[:post_id])
end
end
and here is post controller
class PostsController < ApplicationController
before_action :set_post,only: [:edit,:show,:update,:destroy]
before_action :logged_in_user, only: [:create, :destroy,:new]
before_action :owned_post, only: [:edit, :update, :destroy]
def index
#posts = Post.all.order('created_at DESC').page(params[:page]).per_page(3)
# #posts = Post.all.order('created_at DESC').paginate(page: params[:page])
respond_to do |format|
format.html
format.js
format.json { render json: #projects }
end
end
def new
#post = current_user.posts.build
end
def create
if #post = current_user.posts.create(post_params)
flash[:success] = "Your post has been created!"
redirect_to posts_path
else
flash.now[:alert] = "Your new post couldn't be created! Please check the form."
render :new
end
end
def show
end
def destroy
#post.destroy
redirect_to posts_path
end
def edit
end
def update
if #post.update(post_params)
flash[:success] = "Post updated."
redirect_to posts_path
else
flash.now[:alert] = "Update failed. Please check the form."
render :edit
end
end
private
def owned_post
unless current_user == #post.user
flash[:alert] = "That post doesn't belong to you!"
redirect_to root_path
end
end
def set_post
#post = Post.find(params[:id])
end
def post_params
params.require(:post).permit(:image, :caption)
end
end
and here is JavaScript in asset to load more comment loadmorecomment.js
$( document ).ready(function() {
$('.more-comments').click( function() {
// alert("ok roi day");
$(this).on('ajax:success', function(event, data, status, xhr) {
event.preventDefault();
var postId = $(this).data("post-id");
$("#comments_" + postId).html(data);
$("#comments-paginator-" + postId).html("<a id='more-comments' data-post-id=" + postId + " data-type='html' data-remote='true' href='/posts/" + postId + "/comments'>show more comments</a>");
console.log("<a id='more-comments' data-post-id=" + postId + " data-type='html' data-remote='true' href='/posts/" + postId + "/comments'>show more comments</a>");
});
});
});
but when I click nothing happens, but in the console it says:
Started GET "/posts/25/comments" for 127.0.0.1 at 2017-08-12 18:39:49 +0700
Processing by CommentsController#index as HTML
Parameters: {"post_id"=>"25"}
Post Load (0.2ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT ? [["id", 25], ["LIMIT", 1]]
Rendering comments/index.html.erb
Comment Load (0.3ms) SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = ? ORDER BY created_at ASC [["post_id", 25]]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 53], ["LIMIT", 1]]
CACHE User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 53], ["LIMIT", 1]]
CACHE User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 53], ["LIMIT", 1]]
CACHE User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 53], ["LIMIT", 1]]
CACHE User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 53], ["LIMIT", 1]]
CACHE User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 53], ["LIMIT", 1]]
Rendered collection of comments/_comment.html.erb [5 times] (14.1ms)
Rendered comments/index.html.erb (16.6ms)
Completed 200 OK in 20ms (Views: 17.0ms | ActiveRecord: 0.8ms)
Related
I was trying to work through Section 5 of Working with JavaScript in Rails http://guides.rubyonrails.org/working_with_javascript_in_rails.html .
Issue I have is that the new user isn't displayed in the show page until a refresh the entire page. I think I've replicated all the code correctly, but can't see what's wrong.
users_controller
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
def index
#users = User.all
#user = User.new
end
...
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.js
format.json { render json: #user, status: :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
user/index.html.erb
<b>Users</b>
<ul id="users">
<%= render #users %>
</ul>
<br>
<%= form_with(model: #user) do |f| %>
<%= f.label :name %><br>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
user/create.js.erb
$("<%= escape_javascript(render #user) %>").appendTo("#users");
logs
started POST "/users" for 127.0.0.1 at 2018-03-30 17:23:36 +0100
Processing by UsersController#create as JS
Parameters: {"utf8"=>"✓", "authenticity_token"=>"xMBe+h9zi5rWE8JXltYw1fGwQUP8AL2iWaaaGVqwbPvYavJgv7eQ0J5hwRL9xkb2S0pnose3X6oo+YXywvlcaQ==", "user"=>{"name"=>"Dave"}, "commit"=>"Create User"}
(0.2ms) BEGIN
SQL (0.7ms) INSERT INTO "users" ("name", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["name", "Dave"], ["created_at", "2018-03-30 16:23:36.474360"], ["updated_at", "2018-03-30 16:23:36.474360"]]
(6.3ms) COMMIT
Rendering users/create.js.erb
Rendered users/_user.html.erb (0.3ms)
Rendered users/create.js.erb (3.7ms)
Completed 200 OK in 28ms (Views: 13.6ms | ActiveRecord: 7.3ms)
Started GET "/users" for 127.0.0.1 at 2018-03-30 17:23:38 +0100
Processing by UsersController#index as HTML
Rendering users/index.html.erb within layouts/application
User Load (0.3ms) SELECT "users".* FROM "users"
Rendered collection of users/_user.html.erb [3 times] (0.4ms)
Rendered users/index.html.erb within layouts/application (5.4ms)
Completed 200 OK in 54ms (Views: 49.7ms | ActiveRecord: 0.3ms)
I'm implementing comments as a nested resource for an events app and hitting one issue after another. Initially it worked fine, however, the only functionality they had was create & destroy. I want to add an edit function using Ajax/remote: true for same page editing (never done it before) and I've hit a wall. The edit link_to doesn't/has never worked and now even the create function doesn't work. This is what's coming through on the development log -
Processing by CommentsController#create as JS
Parameters: {"utf8"=>"✓", "comment"=>{"body"=>"Comment."}, "commit"=>"Create Comment", "event_id"=>"27"}
[1m[36mComment Load (0.1ms)[0m [1m[34mSELECT "comments".* FROM "comments" WHERE "comments"."id" = ? LIMIT ?[0m [["id", nil], ["LIMIT", 1]]
Completed 404 Not Found in 1ms (ActiveRecord: 0.1ms)
ActiveRecord::RecordNotFound (Couldn't find Comment with 'id'=):
I've tried all sorts of different parameters via trial and error but the 'id' issue keeps springing up. Here's my code -
comments_controller.rb
class CommentsController < ApplicationController
before_action :set_comment, only: [:show, :create, :edit, :update, :destroy]
def create
#event = Event.find(params[:event_id])
#comment = #event.comments.create(comment_params)
#comment.user_id = current_user.id
if #comment.save
redirect_to #event
else
render 'new'
end
end
# GET /comments/1/edit
def edit
#event = #comment.event
#comment = #event.comments.find(params[:id])
respond_to do |f|
f.js
f.html
end
end
def show
end
def update
if #comment.update(comment_params)
redirect_to #event, notice: "Comment was successfully updated!"
else
render 'edit'
end
end
def destroy
#event = Event.find(params[:event_id])
#comment = #event.comments.find(params[:id])
#comment.destroy
redirect_to event_path(#event)
end
private
def set_comment
#comment = Comment.find(params[:id])
end
def set_event
#event = Event.find(params[:event_id])
end
def comment_params
params.require(:comment).permit(:name, :body)
end
end
_comment.html.erb
<div class="comment clearfix">
<div class="comment_content">
<div id="<%=dom_id(comment)%>" class="comment">
<p class="comment_name"><strong><%= comment.name %></strong></p>
<p class="comment_body"><%= comment.body %></p>
</div>
<p><%= link_to 'Edit', edit_event_comment_path([comment.event, comment]), id: "comment", remote: true %></p>
<p><%= link_to 'Delete', [comment.event, comment],
method: :delete,
class: "button",
data: { confirm: 'Are you sure?' } %></p>
</div>
</div>
_form.html.erb
<%= simple_form_for([#event, #comment], remote: true) do |f| %>
<%= f.label :comment %><br>
<%= f.text_area :body %><br>
<br>
<%= f.button :submit, label: 'Add Comment', class: "btn btn-primary" %>
<% end %>
edit.js.erb
$('#comment').append('<%= j render 'form' %>');
I think I'm getting mixed up with the 'id's for this thing and how to get the remote: true function working on the page. I don't want to accept defeat but I may have to if I don't get this working.
UPDATE -
When I try and edit an existing comment I get this in my development log -
Started GET "/events/27%2F32/comments/27/edit" for ::1 at 2017-05-24 12:28:20 +0100
Processing by CommentsController#edit as JS
Parameters: {"event_id"=>"27/32", "id"=>"27"}
[1m[36mComment Load (0.1ms)[0m [1m[34mSELECT "comments".* FROM "comments" WHERE "comments"."id" = ? LIMIT ?[0m [["id", 27], ["LIMIT", 1]]
Completed 404 Not Found in 1ms (ActiveRecord: 0.1ms)
ActiveRecord::RecordNotFound (Couldn't find Comment with 'id'=27):
The route doesn't make sense - "/events/27%2F32/comments/27/edit" - the comment id should be 32 and the event id 27.
routes.rb
Rails.application.routes.draw do
devise_for :users, :controllers => { omniauth_callbacks: "omniauth_callbacks", registrations: "registrations" }
resources :users
# the above resource draws out routes for user profiles
resources :events do
resources :comments
resources :bookings
end
root 'events#index'
change
before_action :set_comment, only: [:show, :create, :edit, :update, :destroy]
to
before_action :set_comment, only: [:show, :edit, :update, :destroy]
you can't set comment when you are creating it.
Also, as discussed in the comments, your edit link should be,
<%= link_to 'Edit', [comment.event, comment], id: "comment", remote: true %>
I have 2 model Post and Comment, where Post has-many Comments and Comment belongs_to Post.
Every thing working fine with creation of posts and comments for that posts.
Now I have a requirement where when I click on "create new comment" in posts/show page, I want to show the comments/_form in modal.
comments_controller.rb:
class CommentsController < ApplicationController
before_action :set_comment, only: [:show, :edit, :update, :destroy]
# GET /comments
# GET /comments.json
def index
#comments = Comment.all
respond_with(#comments)
end
# GET /comments/1
# GET /comments/1.json
def show
respond_with(#comments)
end
# GET /comments/new
def new
#post = Post.find(params[:post_id])
#comment = #post.comments.build
end
# GET /comments/1/edit
def edit
#post = Post.find(params[:post_id])
end
# POST /comments
# POST /comments.json
def create
#post = Post.find(params[:post_id])
#comment = #post.comments.create(comment_params)
respond_to do |format|
if #comment.save
format.html { redirect_to(#comment, :notice => 'Article was successfully created.') }
format.xml { render :xml => #comment, :status => :created, :location => #comment }
format.js
else
format.html { render :action => "new" }
format.xml { render :xml => #comment.errors, :status => :unprocessable_entity }
format.js
end
end
end
# PATCH/PUT /comments/1
# PATCH/PUT /comments/1.json
def update
#post = Post.find(params[:post_id])
#comment.update(comment_params)
redirect_to post_path(#post)
end
# DELETE /comments/1
# DELETE /comments/1.json
def destroy
#comment.destroy
respond_to do |format|
format.html { redirect_to comments_url, notice: 'Comment was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_comment
#comment = Comment.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def comment_params
params.require(:comment).permit(:commenter, :description)
end
end
posts/show.html.erb:
<%= link_to 'New Coment', new_post_comment_path(#post), :id => 'create_comment' %>
comments/new.html.erb:
<div id="content">
<h1>New Comment</h1>
<%= render 'form' %>
</div>
comments/_form.html.erb:
<%= form_for([#post, #comment], :remote => true) do |f| %>
<div class="field">
<%= f.label :commenter %><br>
<%= f.text_field :commenter %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_field :description %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
comments/create.js.erb:
<%- if #comment.errors.any? %>
console.log('Error');
$('#dialog-form').html('<%= escape_javascript(render('form')) %>');
<%- else %>
console.log('Created');
$('#dialog-form').dialog('close');
$('#dialog-form').remove();
$('table').append('<%= escape_javascript(render(#comment)) %>');
<%- end %>
I don't know where I went wrong. When I click on "create comment" it is redirecting to new page instead of pop-up model and even couldn't create comment.
Please help.
Create a partial for showing comment form.
Render this partial to post show page as hidden.
show hidden partial.
Example:
<%= link_to 'Show Modal', "#", data: {toggle: "modal", target: "#modal"} %>
hidden partial
<div class="modal hide fade" id="modal" title="My modal">
/* your comment form */
/* render comment form */
</div>
Just make sure target is your hidden partial id.
I have a save_video action on my NodesController that does this:
format.html { redirect_to video_tag_users_path(#video) }
What I want to happen is when it calls that action, it should render my tag_users.js.erb, but it is not.
This is my tag_users action:
def tag_users
authorize! :read, #family_tree
#video = Video.find(params[:video_id])
#node = #video.node
respond_to do |format|
format.html
format.js
end
redirect_to root_path
end
This is the log of what is happening:
Redirected to http://localhost:3000/videos/164/tag_users
Completed 302 Found in 23ms (ActiveRecord: 12.3ms)
Started GET "/videos/164/tag_users" for 127.0.0.1 at 2015-03-20 08:24:09 -0500
Processing by VideosController#tag_users as HTML
Parameters: {"video_id"=>"164"}
# truncated for brevity
Rendered videos/tag_users.html.erb within layouts/application (0.2ms)
This is the file I want it to render: tag_users.js.erb
$("#add-video-step-3").html("<%= escape_javascript(render 'videos/tag_users_in_video') %>");
Which then renders this modal _tag_users_in_video.html.erb:
<div class="bootstrap-styles" id="add-video-step-5">
<div class="modal-header">
<div class="titles clearfix">
<h2>Tag Users</h2>
<p><i>Step 3 of 3</i></p>
</div>
</div>
<div class="modal-body">
<div class="content">
<div>Tag someone</div>
<%= simple_form_for #node, url: add_tagged_user_node_path(#node), method: :post do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.association :user, label: "Users", collection: #users, as: :check_boxes, checked: #node.user_tags %>
</div>
<div class="form-actions">
<%= f.button :submit, class: "btn btn-success ladda-button" %>
</div>
<% end %>
</div>
</div>
<div class="modal-footer">
</div>
</div>
Edit 1
So I changed the respond_to block in my tag_users action to this:
render 'tag_users.js'
But now it is actually rendering the JS rather than executing it and rendering the modal I want it to render.
i.e. this is what shows up in my browser, it redirects to URL localhost/videos/167/tag_users.js:
$("#add-video-step-3").html("<div class=\"bootstrap-styles\" id=\"add-video-step-5\"> \n <div class=\"modal-header\">\n <div class=\"titles clearfix\">\n <h2>Tag Users<\/h2>\n <p><i>Step 3 of 3<\/i><\/p>\n <\/div>\n <\/div>\n <div class=\"modal-body\">\n <div class=\"content\">\n <div>Tag someone<\/div>\n <form accept-charset=\"UTF-8\" action=\"/nodes/40/add_tagged_user\" class=\"simple_form edit_node\" id=\"edit_node_40\" method=\"post\" novalidate=\"novalidate\"><div style=\"display:none\"><input name=\"utf8\" type=\"hidden\" value=\"✓\" /><input name=\"authenticity_token\" type=\"hidden\" value=\"Jj8CsHGzcNJJuJn9HGWjNaSjIfSJaZ8N81vmZ+Zp6KQ=\" /><\/div>\n \n \n <div class=\"form-inputs\">\n <div class=\"control-group check_boxes optional node_user\"><label class=\"check_boxes optional control-label\">Users<\/label><div class=\"controls\"><label class=\"checkbox\"><input class=\"check_boxes optional\" id=\"node_user_id_true\" name=\"node[user_id][]\" type=\"checkbox\" value=\"true\" />Yes<\/label><label class=\"checkbox\"><input class=\"check_boxes optional\" id=\"node_user_id_false\" name=\"node[user_id][]\" type=\"checkbox\" value=\"false\" />No<\/label><input name=\"node[user_id][]\" type=\"hidden\" value=\"\" /><\/div><\/div>\n <\/div> \n\n <div class=\"form-actions\">\n <input class=\"btn btn btn-success ladda-button\" name=\"commit\" type=\"submit\" value=\"Update Node\" />\n <\/div>\n<\/form> <\/div>\n <\/div>\n <div class=\"modal-footer\">\n <\/div>\n<\/div>");
That basically means that it is not rendering the HTML like I expect it to, but just spitting out the HTML from the view _tag_users_in_video.html.erb partial.
What I want to happen is for it to pop-up a modal that looks like the modal with id=add-video-step-3, but with the content I specified in _tag_users_in_video.html.erb.
Edit 2
The server log for the above action is:
Started GET "/videos/168/tag_users.js" for 127.0.0.1 at 2015-03-20 10:03:56 -0500
Processing by VideosController#tag_users as JS
Parameters: {"video_id"=>"168"}
User Load (1.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = 57 ORDER BY "users"."id" ASC LIMIT 1
FamilyTree Load (0.9ms) SELECT "family_trees".* FROM "family_trees" WHERE "family_trees"."user_id" = $1 LIMIT 1 [["user_id", 57]]
(1.1ms) SELECT COUNT(*) FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL))) [["user_id", 57]]
Membership Load (1.6ms) SELECT "memberships".* FROM "memberships" WHERE "memberships"."user_id" = 57 AND "memberships"."family_tree_id" = 57
Video Load (1.1ms) SELECT "videos".* FROM "videos" WHERE "videos"."id" = $1 LIMIT 1 [["id", 168]]
Node Load (1.1ms) SELECT "nodes".* FROM "nodes" WHERE "nodes"."media_id" = $1 AND "nodes"."media_type" = $2 LIMIT 1 [["media_id", 168], ["media_type", "Video"]]
ActsAsTaggableOn::Tag Load (1.8ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2 AND "taggings"."context" = 'user_tags' [["taggable_id", 41], ["taggable_type", "Node"]]
Rendered videos/_tag_users_in_video.html.erb (23.6ms)
Rendered videos/tag_users.js.erb (25.5ms)
Completed 200 OK in 196ms (Views: 23.1ms | ActiveRecord: 84.6ms)
Edit 3
So I added the JS render to the format.html inside my save_video action like you suggest. This is the code:
respond_to do |format|
if #node
format.html { render 'tag_users.js' }
format.js
end
end
This is what the result looks like:
Whereas I am trying to get it to look like this:
Edit 4
This is the save_video method in my controller (I left commented out code to see what has been tried with no success):
def save_video
authorize! :read, #family_tree
#video = Video.find(params[:video_id])
if params[:status].to_i == 200
#video.update_attributes(:yt_video_id => params[:id].to_s, :is_complete => true)
#node = current_user.nodes.create!(family_tree: #family_tree, media: #video, name: #video.title, circa: #video.circa)
if #node
render 'tag_users.js'
end
# respond_to do |format|
# if #node
# format.html { }
# format.js
# end
# end
else
Video.delete_video(#video)
end
# respond_to do |format|
# format.html { redirect_to video_tag_users_path(#video, #node) }
# format.js
# end
# redirect_to root_path
# redirect_to video_tag_users_path(#video, #node)
end
Here is the server log for this permutation of the save_video action:
Started GET "/videos/172/save_video?status=200&id=bMaCxSIbJYU" for 127.0.0.1 at 2015-03-20 13:39:19 -0500
Processing by VideosController#save_video as HTML
Parameters: {"status"=>"200", "id"=>"bMaCxSIbJYU", "video_id"=>"172"}
User Load (1.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = 57 ORDER BY "users"."id" ASC LIMIT 1
FamilyTree Load (1.0ms) SELECT "family_trees".* FROM "family_trees" WHERE "family_trees"."user_id" = $1 LIMIT 1 [["user_id", 57]]
(1.2ms) SELECT COUNT(*) FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL))) [["user_id", 57]]
Membership Load (1.4ms) SELECT "memberships".* FROM "memberships" WHERE "memberships"."user_id" = 57 AND "memberships"."family_tree_id" = 57
Video Load (0.9ms) SELECT "videos".* FROM "videos" WHERE "videos"."id" = $1 LIMIT 1 [["id", 172]]
(0.9ms) BEGIN
SQL (1.3ms) UPDATE "videos" SET "is_complete" = $1, "updated_at" = $2, "yt_video_id" = $3 WHERE "videos"."id" = 172 [["is_complete", "t"], ["updated_at", "2015-03-20 18:39:19.959122"], ["yt_video_id", "bMaCxSIbJYU"]]
(1.5ms) COMMIT
(0.9ms) BEGIN
SQL (5.4ms) INSERT INTO "nodes" ("created_at", "family_tree_id", "media_id", "media_type", "name", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["created_at", "2015-03-20 18:39:19.967237"], ["family_tree_id", 57], ["media_id", 172], ["media_type", "Video"], ["name", "Outro 10PP"], ["updated_at", "2015-03-20 18:39:19.967237"], ["user_id", 57]]
(1.2ms) COMMIT
ActsAsTaggableOn::Tag Load (1.7ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2 AND "taggings"."context" = 'user_tags' [["taggable_id", 45], ["taggable_type", "Node"]]
Rendered videos/_tag_users_in_video.html.erb (10.3ms)
Rendered videos/tag_users.js.erb (12.7ms)
Edit 5
There is no front-end part that sends request to save_video. What happens is, the user fills out the form that appears in this modal:
<div id="overlay"> </div>
<div class="popup" id="add-video-step-4" data-step="4" data-intro="GETS TO UPLOADING">
<div class="titles clearfix">
<h2>Upload a Video</h2>
<p><i>Step 1 of 3</i></p>
</div>
<div class="content">
<% if #family_tree %>
<%= simple_form_for([#family_tree, #video], :remote => true) do |f| %>
<div class="column">
<div class="f-row">
<%= f.input :title, label: "Title:" %>
</div>
<div class="f-row">
<%= f.input :description,label: "Description:" %>
</div>
<div class="f-row">
<%= f.input :circa, as: :datepicker, start_year: Date.today.year - 5, label: "Circa:" %>
</div>
<div class="f-row">
<label for="family">Family in this video:</label>
<%= f.collection_select :user_ids, #family_tree.members.order(:first_name), :id, :first_name, {}, {multiple: true} %>
</div>
</div>
<%= f.button :submit, "Add Video", id: "video-submit" %>
<% end %>
<% end %>
</div> <!-- //content -->
</div> <!-- //popup -->
That modal then sends the request to this Create action in my Video controller:
def create
authorize! :read, #family_tree
#video = Video.new(video_params)
respond_to do |format|
if #video.save
format.html { redirect_to video_upload_path(#video) }
# format.json { render action: 'show', status: :created, location: #video }
else
format.html { render action: 'new' }
format.json { render json: #video.errors, status: :unprocessable_entity }
end
end
end
Which, if successful, then sends the request to this Video#Upload action:
def upload
authorize! :read, #family_tree
#video = Video.find(params[:video_id])
#upload_info = Video.token_form(#video, video_save_video_url(#video))
respond_to do |format|
## Note that I have been tinkering with this, but it doesn't work properly yet
format.html { redirect_to video_tag_users_path(#video, #node) }
format.js
end
end
Which first sends to the video_save in the assignment statement.
Hope that provides clarity.
Edit 6
This is the contents of my application.js
//= require jquery
//= require jquery_ujs
//= require best_in_place
//= require bootstrap-sprockets
//= require jquery-ui/datepicker
//= require best_in_place.jquery-ui
//= require jquery.purr
//= require best_in_place.purr
//= require bootstrap.file-input
//= require chosen.jquery
//= require main.js
//= require spin.min
//= require ladda.min
//= require masonry.js
//= require introjs
//= require pnotify
$(document).ready(function(){
$("input.datepicker").datepicker();
/* Activating Best In Place && Include Success Highlighting & Bounce for comments & videos */
$(".best_in_place").best_in_place().bind("ajax:success", function () {$(this).closest('p, h5').effect('highlight').effect("bounce", { times:3 }, { duration:400}).dequeue(); });
$('.dropdown-toggle').dropdown();
$('#unread-notification').click(function(){
var url = $(this).data('read-url');
$.ajax({
type: "PUT",
url: url
});
});
});
Edit 7
Here is the server log after the first create is called:
Started POST "/family_trees/57/videos" for 127.0.0.1 at 2015-03-23 15:05:46 -0500
Processing by VideosController#create as JS
Parameters: {"utf8"=>"✓", "video"=>{"title"=>"Hello There", "description"=>"This is an interesting video", "circa"=>"", "user_ids"=>[""]}, "commit"=>"Add Video", "family_tree_id"=>"57"}
User Load (15.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = 57 ORDER BY "users"."id" ASC LIMIT 1
FamilyTree Load (5.6ms) SELECT "family_trees".* FROM "family_trees" WHERE "family_trees"."user_id" = $1 LIMIT 1 [["user_id", 57]]
FamilyTree Load (2.2ms) SELECT "family_trees".* FROM "family_trees" WHERE "family_trees"."id" = $1 LIMIT 1 [["id", 57]]
(2.3ms) SELECT COUNT(*) FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL))) [["user_id", 57]]
Membership Load (1.8ms) SELECT "memberships".* FROM "memberships" WHERE "memberships"."user_id" = 57 AND "memberships"."family_tree_id" = 57
(2.6ms) BEGIN
SQL (6.1ms) INSERT INTO "videos" ("created_at", "description", "title", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["created_at", "2015-03-23 20:05:46.637067"], ["description", "This is an interesting video"], ["title", "Hello There"], ["updated_at", "2015-03-23 20:05:46.637067"]]
(2.8ms) COMMIT
Redirected to http://localhost:3000/videos/177/upload
Completed 302 Found in 84ms (ActiveRecord: 39.2ms)
Started GET "/videos/177/upload" for 127.0.0.1 at 2015-03-23 15:05:46 -0500
Processing by VideosController#upload as JS
Parameters: {"video_id"=>"177"}
User Load (2.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = 57 ORDER BY "users"."id" ASC LIMIT 1
FamilyTree Load (1.9ms) SELECT "family_trees".* FROM "family_trees" WHERE "family_trees"."user_id" = $1 LIMIT 1 [["user_id", 57]]
(1.3ms) SELECT COUNT(*) FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL))) [["user_id", 57]]
Membership Load (1.7ms) SELECT "memberships".* FROM "memberships" WHERE "memberships"."user_id" = 57 AND "memberships"."family_tree_id" = 57
Video Load (2.8ms) SELECT "videos".* FROM "videos" WHERE "videos"."id" = $1 LIMIT 1 [["id", 177]]
Rendered videos/_upload_video.html.erb (4.6ms)
Rendered videos/upload.js.erb (7.6ms)
Completed 200 OK in 344ms (Views: 23.7ms | ActiveRecord: 10.3ms)
Edit 8
_upload_video.html.erb
<div class="bootstrap-styles" id="add-video-step-3">
<div class="modal-header">
<div class="titles clearfix">
<h2>Upload a Video</h2>
<p><i>Step 2 of 3</i></p>
</div>
</div>
<div class="modal-body">
<div class="content">
<%= form_tag #upload_info[:url], :multipart => true do %>
<%= hidden_field_tag :token, #upload_info[:token] %>
<div class="uploader clearfix">
<%= file_field_tag :file, title: 'SELECT FILE TO UPLOAD', class: "upload" %>
</div>
<button class="btn btn-success ladda-button" data-color="green" data-style="expand-left"><span class="ladda-label">Upload Video</span><span class="ladda-spinner"></span></button>
<% end %>
</div>
</div>
<div class="modal-footer">
</div>
</div>
upload.js.erb
$("#add-video-step-4").html("<%= escape_javascript(render 'videos/upload_video') %>");
Assuming this is your code
def tag_users
authorize! :read, #family_tree
#video = Video.find(params[:video_id])
#node = #video.node
respond_to do |format|
render format.html
format.js
end
end
And, by looking at output i can say that server is receiving HTML as format. Since, you want to execute script you must send datatype to script.
Looking at html code, i think you have to pass data: {type: "script"} to simple_form function, so it will be
<div id="overlay"> </div>
<div class="popup" id="add-video-step-4" data-step="4" data-intro="GETS TO UPLOADING">
<div class="titles clearfix">
<h2>Upload a Video</h2>
<p><i>Step 1 of 3</i></p>
</div>
<div class="content">
<% if #family_tree %>
<%= simple_form_for([#family_tree, #video], :remote => true, data: {type: "script"} ) do |f| %>
<div class="column">
<div class="f-row">
<%= f.input :title, label: "Title:" %>
</div>
<div class="f-row">
<%= f.input :description,label: "Description:" %>
</div>
<div class="f-row">
<%= f.input :circa, as: :datepicker, start_year: Date.today.year - 5, label: "Circa:" %>
</div>
<div class="f-row">
<label for="family">Family in this video:</label>
<%= f.collection_select :user_ids, #family_tree.members.order(:first_name), :id, :first_name, {}, {multiple: true} %>
</div>
</div>
<%= f.button :submit, "Add Video", id: "video-submit" %>
<% end %>
<% end %>
</div> <!-- //content -->
</div> <!-- //popup -->
See here Why I need add "data: {type: "script"}" on remote link with rails / ajax
If you want to use the redirect, you might just try adding a format to the redirect path:
format.html { redirect_to video_tag_users_path(#video, format: :js) }
Every time I hit submit in my rails app it sends the request 2x. I can get rid of the second partial by hitting refresh. This is a nested app. Todo has_many Items. I included the controllers and the create and the partials.
I included a photo to make a bit more clear.
create.js.erb
$('.todo-items').prepend("<%= escape_javascript(render(#item)) %>");
Items Controller:
class ItemsController < ApplicationController
before_action :set_item, only: [:show, :edit, :update, :destroy]
before_action :set_todo
respond_to :html, :js
# GET /items
# GET /items.json
def index
#items = Item.all
end
# GET /items/1
# GET /items/1.json
def show
#item = Item.find(params[:id])
end
# GET /items/new
def new
#item = #todo.items.build
end
# GET /items/1/edit
def edit
#item = Items.find(params[:id])
end
# POST /items
# POST /items.json
def create
#item = #todo.items.build(item_params)
respond_with(#item) do |format|
if #item.save
format.html { redirect_to [#todo], notice: 'Item was successfully created.' }
format.json { render :show, status: :created, location: #item }
else
format.html { render :new }
format.json { render json: #item.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /items/1
# PATCH/PUT /items/1.json
def update
#item = Item.find(params[:id])
respond_to do |format|
if #item.update(item_params)
format.html { redirect_to [#todo, #item], notice: 'Item was successfully updated.' }
format.json { render :show, status: :ok, location: #item }
else
format.html { render :edit }
format.json { render json: #item.errors, status: :unprocessable_entity }
end
end
end
# DELETE /items/1
# DELETE /items/1.json
def destroy
#item = Item.find(params[:id])
#item.destroy
respond_to do |format|
format.html { redirect_to items_path }
format.json { head :no_content }
format.js { render layout: false }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_item
#item = Item.find(params[:id])
end
def set_todo
#todo = Todo.find(params[:todo_id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def item_params
params.require(:item).permit(:content, :todo_id)
end
end
Todos Controller
class TodosController < ApplicationController
respond_to :html, :js
before_action :set_todo, only: [:show, :edit, :update, :destroy]
# GET /todos
# GET /todos.json
def index
#todos = Todo.all
#todo = Todo.new
end
# GET /todos/1
# GET /todos/1.json
def show
#todo= Todo.find(params[:id])
end
# GET /todos/new
def new
#todo = Todo.new
#3.times{#todo.items.build}
end
# GET /todos/1/edit
def edit
end
# POST /todos
# POST /todos.json
def create
#todo = Todo.new(todo_params)
##todo.items.build
respond_to do |format|
if #todo.save
format.html { redirect_to todo_path, notice: 'Todo was successfully created.' }
format.json { render :show, status: :created, location: #todo }
else
format.html { render :new }
format.json { render json: #todo.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /todos/1
# PATCH/PUT /todos/1.json
def update
#todo = Todo.find(params[:id])
respond_to do |format|
if #todo.update(todo_params)
format.html { redirect_to todos_url, notice: 'Todo was successfully updated.' }
format.json { render :show, status: :ok, location: #todo }
else
format.html { render :edit }
format.json { render json: #todo.errors, status: :unprocessable_entity }
end
end
end
# DELETE /todos/1
# DELETE /todos/1.json
def destroy
#todo.destroy
#todo.items.destroy
respond_to do |format|
format.html { redirect_to todos_url, notice: 'Todo was successfully destroyed.' }
format.json { head :no_content }
end
end
def todo_completed
#todo = Todo.find(params[:id])
#todo.completed = true
if #todo.save
flash[:notice] = "Task was completed."
else
flash[:error] = "There was an error completing the task."
end
#redirect_to tasks_path
respond_with(#todo) do |f|
f.html { redirect_to todos_path }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_todo
#todo = Todo.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def todo_params
params.require(:todo).permit(:title, :completed, items_attributes: [:content,:completed, :_destroy])
end
end
This is the show page the one in the photo for Todo. It is rendering the items underneath that specific todo.
<p>Here are all the things you need to complete</p>
<div class="todo-items">
<%= render partial: 'items/item' %>
</div>
<br>
<div class='new-item'>
<%= render 'items/form'%>
</div>
<%= link_to 'Back', todos_path %>
Items/item
<p>todo/show this is the partial <%= #todo.title %></p>
<table class='table table-bordered'>
<thead>
<tr>
<th>Description</th>
<th> Time Left </th>
<th> Mark Complete </th>
</tr>
</thead>
<tbody>
<% #todo.items.each do |item| %>
<tr>
<td><%= link_to item.content, [#todo, item] %></td>
<td><%= item.days_left %>
<td>
<%= link_to todo_item_path(#todo,item), method: :delete, data: { confirm: 'Are you sure?' }, remote: true, class: 'delete_item' do %>
<i class="fa fa-check"></i>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
<br>
<p>end of partial item</p>
Item/form
<p>
<strong>Todo:</strong>
<%= #todo.title %>
</p>
<%= form_for [#todo, #todo.items.build], remote: true do |f| %>
<div class="field">
<%= f.label :content %><br>
<%= f.text_field :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
A little more info from the console. It starts when I click on the list(Groceries) and end with me hitting submit to add the item
Started GET "/todos/25" for 127.0.0.1 at 2014-10-08 19:19:58 -0500
Processing by TodosController#show as HTML
Parameters: {"id"=>"25"}
Todo Load (0.3ms) SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? LIMIT 1 [["id", 25]]
CACHE (0.0ms) SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? LIMIT 1 [["id", "25"]]
Item Load (0.4ms) SELECT "items".* FROM "items" WHERE "items"."todo_id" = ? [["todo_id", 25]]
Rendered items/_item.html.erb (42.9ms)
Rendered items/_form.html.erb (17.3ms)
Rendered todos/show.html.erb within layouts/application (66.6ms)
Completed 200 OK in 346ms (Views: 339.5ms | ActiveRecord: 1.3ms)
Started POST "/todos/25/items" for 127.0.0.1 at 2014-10-08 19:20:12 -0500
Processing by ItemsController#create as JS
Parameters: {"utf8"=>"✓", "item"=>{"content"=>"Cereal"}, "commit"=>"Create Item", "todo_id"=>"25"}
Todo Load (0.2ms) SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? LIMIT 1 [["id", 25]]
(0.3ms) begin transaction
Todo Load (0.2ms) SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? LIMIT 1 [["id", 25]]
SQL (0.5ms) INSERT INTO "items" ("content", "created_at", "todo_id", "updated_at") VALUES (?, ?, ?, ?) [["content", "Cereal"], ["created_at", "2014-10-09 00:20:12.060569"], ["todo_id", 25], ["updated_at", "2014-10-09 00:20:12.060569"]]
(148.1ms) commit transaction
Item Load (0.2ms) SELECT "items".* FROM "items" WHERE "items"."todo_id" = ? [["todo_id", 25]]
Rendered items/_item.html.erb (9.8ms)
Rendered items/create.js.erb (12.5ms)
Completed 200 OK in 180ms (Views: 15.2ms | ActiveRecord: 149.4ms)
The problem is with your create.js.erb file. You have below code:
$('.todo-items').prepend("<%= escape_javascript(render(#item)) %>");
In this code you are pre-pending html in todo-items you should replace items each time instead. like below :
$('.todo-items').html("<%= escape_javascript(render(#item)) %>");
This will replace html each time with new html.