Rails에서 Ajax 오류 메시지 발행

7788 단어 아약스Rails

목표





Rails에서 Ajax를 사용하여 밸리데이션에 걸렸을 때, 에러 메세지를 발행한다.

Ajax의 예로 주석 기능으로 작성합니다.

환경



환경 rails 6.0.2.2

간단히 User 모델(name 열과 email 열), Topic 모델(content 열 및 user_id 열), Comment 모델(review 열과 user_id 및 topic_id)

Twitter에 비유하면 User가 트윗 (Topic)하고 거기에 User가 Comment한다는 느낌입니다!

다음 모델 연결 및 변형(Comment만 해당)입니다.

user.rb
has_many :topics, dependent: :destroy
has_many :comments, dependent: :destroy

topic.rb
belongs_to :user
has_many :comments, dependent: :destroy

comment.rb
belongs_to :user
belongs_to :topic

validates :review, presence: true, length: { maximum: 150 }

Comment 모델은 review 컬럼이 「로부터의 때」와 「151 문자 이상」일 때에 에러가 됩니다.

컨트롤러



먼저 컨트롤러를 작성합니다.

topics_controller.rb
def show
  @topic = Topic.find[:params]
  @comment = Comment.new
  @comments = @topic.comments
end

comments_controller.rb
def create
    @topic = Topic.find(params[:topic_id])
    @comment = @topic.comments.build(comment_params)
    @comment.user_id = current_user.id
    @comment.save
  end

  def destroy
    @comment = Comment.find(params[:id])
    @comment.destroy
  end

코멘트는 topics/show.html.erb에서 할 수 있도록 하고 있습니다.

보기



다음은 보기

topics/show.html.erb
<div id="comments_area">
    <%= render partial: 'comments/index', locals: { comments: @comments } %>
  </div>
  <div id="error_explanation">
  </div>
  <div id="form_area">
  <% if current_user %>
    <%= render partial: 'comments/form', locals: { comment: @comment, topic: @topic } %>
  <% end %>
</div>

comments/create.js.erb
$("#comments_area").html("<%= j(render 'index', { comments: @comment.topic.comments }) %>")
$("#error_explanation").html("<%= j(render 'error', { comment: @comment }) %>")
$("textarea").val("")

_form.html.erb
<%= form_with(model: [topic, comment]) do |f| %>

<% if comment.errors.any? %>
      <div id="error_explanation">

        <ul>
          <% comment.errors.full_messages.each do |message| %>
            <li><%= message %></li>
          <% end %>
        </ul>
      </div>
  <% end %>

  <div>
    <%= f.label :review %><span style="color: #f00;">(150文字以内)</span><br>
    <%= f.text_area :review,placeholder: "コメントはこちら" %>
  </div>
  <div class="actions mb-3">
    <%= f.submit "コメントをする", class: "btn btn-x btn-outline-secondary" %>
  </div>
<% end %>

comments/_index.html.erb
<% comments.each do |comment| %>
  <% unless comment.id.nil? %>
    <p><%= link_to "#{comment.user.name}さん",user_path(comment.user.id) %></p>
    <p><%= comment.review %></p>
    <% if comment.user == current_user %>
      <p><%= link_to "コメントを削除する",topic_comment_path(comment.topic_id,comment.id),method: :delete, remote: true %></p><hr size="5px" color="black">
    <% end %>
  <% end %>
<% end %>

comments/_error.html.erb
<% if comment.errors.any? %>
  <div class="error_message alert alert-warning">
    <ul>
      <% comment.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
    </ul>
  </div>
<% end %>

흐름으로
①topics/show.html.erb에 액세스하면 _form.html.erb와 _index.html.erb가 표시된다. index는 이미 저장된 코멘트를 보여주는 HTML입니다.

②form에서 「코멘트를 한다」버튼을 누르면, comment 컨트롤러의 create 메소드가 실행된다. 이 때, form_with는 디폴트로 remote: true가 되어 있으므로, 뷰는 「create.js.erb」를 찾는다.
(덧붙여서 local: true라고 하면 create.html.erb를 찾는다)

③create.js.erb의 1행째에서는 id가 comments_area의 곳에 _index.html.erb를 표시시키고 있다.
2행째에서는 똑같이 _error.html.erb를 표시시키고 있다. 단지 에러를 보면, if 구문이 되어 있어 에러가 없으면 표시되지 않는다. 세 번째 줄은 양식의 textarea를 비우는 코드입니다.

이제 오류가 표시됩니다.

기타



일단 루트와 코멘트 삭제의 뷰도 써 둡니다.

routes.rb
resources :topics do
    resources :comments, only: [:create, :destroy]
  end

destroy.js.erb
$("#comments_area").html("<%= j(render 'index', { comments: @comment.topic.comments }) %>")
$("textarea").val("")

이상입니다! 뭔가 이상한 곳 등 있으면, 지적해주세요!

참고 htp://에이후군. 하테나아 ry. jp/엔트리/2016/01/20/001011

좋은 웹페이지 즐겨찾기