在表单上使用ajax提交rails

时间:2018-10-01 01:53:24

标签: ruby-on-rails ruby ajax erb

Started POST "/users/3/tweets" for 127.0.0.1 at 2018-10-01 16:43:04 +0100
Processing by TweetsController#create as JS
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"a4GACc9npDT1aXdadefb62NbUVbAxA11JBQ/NDkCcPOS0l7wyBbJmwvdPdwZ8rZryT6LmxoFxI9wfv2RloLQIQ==", "tweet"=>{"content"=>"hello"}, "commit"=>"Create Tweet", "user_id"=>"3"}
  User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 3], ["LIMIT", 1]]
  ↳ /Users/benherring/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 3], ["LIMIT", 1]]
  ↳ app/controllers/tweets_controller.rb:23
   (0.1ms)  BEGIN
  ↳ app/controllers/tweets_controller.rb:26
  Tweet Create (0.4ms)  INSERT INTO "tweets" ("content", "created_at", "updated_at", "user_id") VALUES ($1, $2, $3, $4) RETURNING "id"  [["content", "hello"], ["created_at", "2018-10-01 15:43:04.707047"], ["updated_at", "2018-10-01 15:43:04.707047"], ["user_id", 3]]
  ↳ app/controllers/tweets_controller.rb:26
   (1.7ms)  COMMIT
  ↳ app/controllers/tweets_controller.rb:26
  Rendering tweets/create.js.erb
  Rendered tweets/create.js.erb (7.3ms)
Completed 500 Internal Server Error in 34ms (ActiveRecord: 2.9ms)


  
ActionView::Template::Error (Missing partial tweets/_index with {:locale=>[:en], :formats=>[:js, :html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :jbuilder]}. Searched in:
  * "/Users/benherring/twitter-clone/app/views"
  * "/Users/benherring/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/devise-4.5.0/app/views"
):
    11: <% if @tweet.errors.any? %>
    12:   refreshForm('<%= j render "tweets/new", user: @user, tweet: @tweet %>');
    13: <% else %>
    14:   addTweet('<%= j render "tweets/index", tweet: @tweet %>');
    15:   refreshForm('<%= j render "tweet/new", user: @user, tweet: Tweet.new %>');
    16: <% end %>
  
app/views/tweets/create.js.erb:14:in `_app_views_tweets_create_js_erb__1236688757229574759_70092102807800'

im尝试使用ajax提交表单,以使页面不会重新加载。该表格目前无需ajax即可工作,但我希望它会更好。香港专业教育学院看过的Rails文档,在这里,我无法理解。香港专业教育学院改变了形式,控制器,并做了一个create.js.erb文件,但没有运气。谢谢

class TweetsController < ApplicationController
  before_action :authenticate_user!, :except => [:index]

   def index
    # @tweets = Tweet.all.order("created_at DESC")
    @tweets = Tweet.paginate(page: params[:page], per_page: 7).order('created_at DESC')

    @tweet = Tweet.new
    @user = current_user
  end

  def show
    @tweet = Tweet.find(params[:id])
  end

  def new
    # @tweet = Tweet.new
    # @user = current_user
  end

  def create
    # @user = current_user
    @user = User.find(params[:user_id])
    @tweet = Tweet.new(tweet_params)
    @tweet.user = @user
    if @tweet.save
         respond_to do |format|
        format.html { redirect_to user_tweets_path }
        format.js
      end
    else
      respond_to do |format|
        format.html { render 'tweets/index' }
        format.js
      end
    end
    # redirect_to user_tweets_path
  end


  def edit
    @tweet = Tweet.find(params[:id])
  end

  def update
    @tweet = Tweet.find(params[:id])
    @tweet.update(tweet_params)
    redirect_to tweets_path
  end

  def upvote
  @tweet = Tweet.find(params[:id])
  @tweet.upvote_by current_user
  # redirect_to :tweets
   if request.xhr?
    head :ok
  else
    redirect_to tweets_path
  end
end

def downvote
  @tweet = Tweet.find(params[:id])
  @tweet.downvote_by current_user
  redirect_to :tweets
end

  private
  def tweet_params
    params.require(:tweet).permit(:content)
  end
end

<%= simple_form_for [ @user ,@tweet], remote: true, id: "form-submit" do |f| %>
       <%= f.input :content, label: "Tweet" %>
       <%= f.button :submit, class: "btn btn-primary" %>
       <% end %>

function refreshForm(innerHTML) {
  const newTweetForm = document.getElementById('new_tweet');
  newTweetForm.innerHTML = innerHTML;
}

function addTweet(tweetHTML) {
  const tweets = document.getElementById('tweets');
  reviews.insertAdjacentHTML('beforeend', reviewHTML);
}

<% if @review.errors.any? %>
  refreshForm('<%= j render "tweets/new", user: @user, tweet: @tweet %>');
<% else %>
  addTweet('<%= j render "tweets/index", tweet: @tweet %>');
  refreshForm('<%= j render "tweet/new", user: @user, tweet: Tweet.new %>');
<% end %>

<h1 class="title text-primary">Home</h1>


<div class="tweet-form">
  <% if user_signed_in? %>
    <%= render 'new',user:@user, tweet:@tweet %>
  <% end %>
</div>
   <br>

<div id="tweets">
<% @tweets.each do |tweet|  %>
  <div class="card">
    <div class="card-description">
      <h4><%= link_to tweet.user.username, user_path(tweet.user) %></h4>
      <p class="tweet-content"><%= tweet.content %></p>
      <p><%= tweet.created_at.strftime("%B %d %Y, %l:%M%P") %></p>
      <%= link_to like_tweet_path(tweet),  method: :put do %>
      <p>Upvote <%= tweet.get_upvotes.size %>
      <% end %>
      <%= link_to dislike_tweet_path(tweet), method: :put do %>
      Downvote <%= tweet.get_downvotes.size %></p>
      <% end %>
    </div>
  </div>
<% end %>
</div>




<div class="pages">
  <%= will_paginate @tweets,renderer: BootstrapPagination::Rails %>
</div>

    config.action_view.embed_authenticity_token_in_remote_forms = true

3 个答案:

答案 0 :(得分:1)

您遇到的错误是对表单提交的javascript响应。特别是这一行:

addTweet('<%= j render "tweets/index", tweet: @tweet %>')

的问题。

ActionView::Template::Error (Missing partial tweets/_index with {:locale=>[:en], :formats=>[:js, :html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :jbuilder]}

您的应用程序中不得包含app/views/_tweets文件

请注意,render "tweets/index"自动在输入的文件名的开头添加下划线,使tweets/index成为tweets/_index

您需要添加呈现索引模板的部分(带有下划线的视图文件)

答案 1 :(得分:0)

我认为您的js.erb中有错字

const tweets = document.getElementById('tweets');
reviews.insertAdjacentHTML('beforeend', reviewHTML);

第二行中的意思是tweets而不是reviews

也在js.erb中

function refreshForm(innerHTML) {
  const newTweetForm = document.getElementById('new_tweet');
  newTweetForm.innerHTML = innerHTML;
}

但是这将在表单内部呈现一个表单,不应该为此获取父元素。您的情况是班级tweet-form

答案 2 :(得分:0)

您的日志显示此错误:

ActionView::Template::Error (Missing partial tweets/_index

这是由以下代码引起的:

addTweet('<%= j render "tweets/index", tweet: @tweet %>');

显然,您没有要渲染的名为tweets/_index的局部文件。

您可以创建此文件并确保其名为_index而不是index吗?