75579


グループの投稿機能を作っていたのですが、投稿ボタンを押したら、バリデーションに失敗しました。circleを入力してください。と表示されるので、rails
cを打ち、Circlepost.firstと入力すると

[code]

    <Circlepost id: 11, content: "k", user_id: 1, created_at: "2021-04-27 03:31:41", updated_at: "2021-04-27 03:31:41", circle_id: nil>
    
[/code]

このようにcircle_idが入っていませんでした。

* * *

circle(グループ)  
user  
circlepost(グループ投稿)

* * *

これはルートに問題があるのかコントローラーに問題があるのかわかりません。ルートやコントローラーをいじってみても分からなかったので、どういったように変更すれば良いか教えていただきたいです。

ちなみにグループの投稿はpostlistというページに表示するようにしています。

### routes.rb

[code]

    
     resources :circles do
        member do
          get :postlist
        end
      end
    
    postlist_circle GET    /circles/:id/postlist(.:format)                                                          circles#postlist
    
[/code]

### /app/controllers/circleposts_controller.rb

[code]

    
     class CirclepostsController < ApplicationController
    before_action :logged_in_user, only: [:create, :destroy]
    before_action :correct_circle,   only: :destroy
    require 'pry'
    
      def create
        @circle = Circle.find_by(id: params[:circle_id])
        @circlepost = current_user.circleposts.build(circlepost_params)
        @circlepost.circle_id = params[:circle_id]
        @circlepost.image.attach(params[:circlepost][:image])
        if @circlepost.save!
          flash[:success] = "投稿しました。"
          redirect_to request.referrer || root_url
        else
          @feed_items = current_user.feed.paginate(page: params[:page])
          render 'static_pages/home'
        end
      end
      
      def destroy
        @circlepost.destroy
        flash[:success] = "投稿を削除しました。"
        redirect_to request.referrer || root_url
      end
    
      private
      
        def circlepost_params
          params.require(:circlepost).permit(:content, :image)
        end
        
        def correct_circle
          @circlepost = current_user.circleposts.find_by(id: params[:id])
          redirect_to root_url if @circlepost.nil?
        end
    end
    
[/code]

### モデル

[code]

    belongs_to :circle, optional: true
    belongs_to :user
    
    ユーザーとグループに関連づけています。※ユーザーとグループ側にも関連付けしています。
    
[/code]

### /app/views/circles/postlist.html.erb

[code]

    
    <% provide(:title, 'postlist') %>
    
      <h3 class="circle-name"><%= @circle.name %></h3>
      <div class="postlist">
        <% if @circle.circle_user?(current_user) %>
          <section class="circlepost_form">
            <%= render 'shared/circlepost_form' %>
          </section>
        <% end %>
              
        <% if @circle.circleposts.any? %>
          <ol class="circleposts">
            <%= render @circleposts %>
          </ol>
          <div class="page">
             <%= will_paginate @circleposts, { :previous_label => '&lt 前へ', :next_label => '次へ &gt' } %>
          </div>
        <% end %>
        </div>
    
    
[/code]

### /app/views/shared/_circlepost_form.html.erb

[code]

    <%= form_with(model: @circlepost, local: true) do |b| %>
      <%= render 'shared/error_messages_second', object: b.object %>
      <div class="field">
        <%= b.text_area :content, placeholder: "(例)　活動時間を変更したので確認してください！" %>
      </div>
      <%= b.submit "投稿", class: "btn btn-warning" %>
      <span class="image">
        <%= b.file_field :image, accept: "image/jpeg,image/gif,image/png" %>
      </span>
    <% end %>
    
[/code]

### ログ

[code]

    Started POST "/circleposts" for 126.227.240.207 at 2021-04-27 14:19:34 +0000
    Cannot render console from 126.227.240.207! Allowed networks: 126.227.199.43, 127.0.0.0/127.255.255.255, ::1
       (1.8ms)  SELECT sqlite_version(*)
       (0.2ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
    Processing by CirclepostsController#create as HTML
      Parameters: {"authenticity_token"=>"pgdArkzFtgJKP1AYL0hjpJTnRBpCaQL47awdeH/E1svA88nIqY/RrdXLROzMzH7BW6L9YRcL4aA8rGPx26PkLg==", "circlepost"=>{"content"=>"d"}, "commit"=>"投稿"}
      User Load (1.1ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
      ↳ app/helpers/sessions_helper.rb:18:in `current_user'
      Circle Load (0.8ms)  SELECT "circles".* FROM "circles" WHERE "circles"."id" IS NULL LIMIT ?  [["LIMIT", 1]]
      ↳ app/controllers/circleposts_controller.rb:7:in `create'
    Completed 422 Unprocessable Entity in 424ms (ActiveRecord: 5.1ms | Allocations: 207665)
    
    
      
    ActiveRecord::RecordInvalid (バリデーションに失敗しました: Circleを入力してくださ
    
[/code]


CC BY-SA 4.0
2021-04-27T14:01:18.823
75540
2021-04-29T13:42:03.823
2021-04-27T14:22:59.187
44916
44916
question
ruby-on-rails ruby
ActiveRecord::RecordInvalidのバリデーションエラー


`circle_id`をコントローラに渡す必要があります。方法は2つあります。  
まず、`app/views/shared/_circlepost_form.html.erb`のフォームの項目から`circle_id`を選択できるようにすることです。この方法のメリットはフォーム以外を修正する必要がないことですが、デメリットとしてはフォームに項目が増えてしまってユーザビリティを損ねる可能性が挙げられます。  
もう一つの方法は、`config/routes.rb`を修正して以下のようにすることです。

[code]

    resources :circles do
        member do
          get :postlist
          resources :circleposts
        end
    end
    
[/code]

こうすることで、Circlepostsの作成先URLが`/circleposts`から`circles/:circle_id/circleposts`に変わり、URLからサークルのIDを取得できるようになります。  
この方法のメリットはユーザー体験を変更しないことです。デメリットは既存のフォームのURLも変更になってしまう点です。

メリットとデメリット、更には実装の難易度などを考慮して決定するとよいかと思います。


CC BY-SA 4.0
2021-04-29T13:42:03.823
75579
2021-04-29T13:42:03.823
442
75540
answer