問題点
RSpecでRequestテストを書いております
以下のようにupdateアクションのテストを行う際に、
"Failure/Error: @article = Article.find_by!(url_token: params[:url_token])
ActiveRecord::RecordNotFound:
Couldn't find Article"
とエラーがでており、解消できません。
spec/requests/articles_spec.rb
require 'rails_helper' RSpec.describe "Articles", type: :request do describe "PATCH #update" do let!(:user) { FactoryBot.create(:user) } let!(:article) { user.articles.create(FactoryBot.attributes_for(:article, title: "test #edit"))} context "パラメーターが妥当な場合" do it "リクエストが成功すること" do patch articles_path, params: { url_token: article.url_token } expect(response).to have_http_status(302) end end end end end
検証
it
以下に下記コードを差し込むと
p Article.last p article.url_token #<Article id: 810, title: "test #edit", content: "Hello World", created_at: "2020-07-29 11:20:25", updated_at: "2020-07-29 11:20:25", user_id: 1109, url_token: "UgBg0MJb_sA", article_token_digest: "$2a$04$GPFQLbz1Uvb/vqpV2rXs/uy/VMdyGGUUpiXObE3zjeq..."> "UgBg0MJb_sA"
と返ってきており、DB上にデータは存在し、
paramsに渡す変数article.url_token
も適切のように思います。
paramsの与え方に問題があるのでしょうか?
development環境のコンソール上だと問題なくfind_by
で該当記事を抽出できます・
気になる点
url_token
属性はbefore_validation
でvalidationが行われる前に生成されるよう、modelにて定義しております。
この辺り問題になりますでしょうか?
app/models/article.rb
ruby
1class Article < ApplicationRecord 2 belongs_to :user 3 has_secure_password :article_token, validations: true 4 attribute :url_token, :string, default: -> { SecureRandom.urlsafe_base64(8) } 5 before_validation :create_article_token 6 validates :title, presence: true, length: { maximum: 100 } 7 validates :content, presence: true 8 9 def to_param 10 url_token 11 end 12 13 private 14 def create_article_token 15 self.article_token = SecureRandom.hex(4) 16 end 17end
articles_controller.rb
class ArticlesController < ApplicationController before_action :set_article, only: [:show, :edit, :update, :destroy] . . . def update respond_to do |format| if @article.update(article_params) format.html { redirect_to @article, notice: 'Article was successfully updated.' } format.json { render :show, status: :ok, location: @article } else format.html { render :edit } format.json { render json: @article.errors, status: :unprocessable_entity } end end end . . . private # Use callbacks to share common setup or constraints between actions. def set_article @article = Article.find_by!(url_token: params[:url_token]) @author = @article.user end # Only allow a list of trusted parameters through. def article_params params.require(:article).permit(:title, :content, :url_token, :article_token) end end
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/29 15:11