質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 7

Ruby on Rails 7は、2021年12月に正式リリースされました。Ruby on Railsのバージョン7であり、フロントエンド開発環境を大幅に刷新。Node.jsを用いない構成がデフォルトになっています。

Q&A

解決済

2回答

754閲覧

ActiveRecordを継承しているモデルに値が設定できない

Hanbe.T

総合スコア36

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 7

Ruby on Rails 7は、2021年12月に正式リリースされました。Ruby on Railsのバージョン7であり、フロントエンド開発環境を大幅に刷新。Node.jsを用いない構成がデフォルトになっています。

0グッド

0クリップ

投稿2023/01/02 14:35

編集2023/01/03 14:17

前提

言語等バージョン
Ruby3.1.3
Rails7.0.4
ActiveRecord7.0.4
DBPostgres 14.6

事象

Rails7のActiveRecordを使用してモデルを作成しました。
そのクラスに対して、newやcreateメソッド引数に値を渡しても反映されない。
インスタンス生成後に、各項目に代入することは可能だった。

ruby

1[2] pry(main)> Sample.new(url: '1', counter: 20) 2=> #<Sample:0x00007fbbcdf95e30 id: nil, url: nil, counter: 0, created_at: nil, updated_at: nil>

確認したいこと

  1. この事象の原因

該当のソースコード

  • app/models/sample.rb

    ruby

    1# frozen_string_literal: true 2 3class Sample < ApplicationRecord 4 attr_accessor :url, :counter 5 6 validates :url, presence: true, uniqueness: true 7 validates :counter, presence: true 8end
  • app/models/application_record.rb
    • 特に変更は加えていない

    ruby

    1# frozen_string_literal: true 2 3class ApplicationRecord < ActiveRecord::Base 4 primary_abstract_class 5end
  • db/schema.rb

    ruby

    1ActiveRecord::Schema[7.0].define(version: 2023_01_02_130059) do 2 # These are extensions that must be enabled in order to support this database 3 enable_extension "plpgsql" 4 5 create_table "samples", force: :cascade do |t| 6 t.string "url", null: false, comment: "URL" 7 t.integer "counter", default: 0, null: false, comment: "カウンタ" 8 t.datetime "created_at", null: false 9 t.datetime "updated_at", null: false 10 t.index ["url"], name: "index_samples_on_url", unique: true 11 end 12 13end

試したこと

  1. createメソッドに引数として渡した→反映されず

    ruby

    1[1] pry(main)>Sample.create(url: '1', counter: 10) 2 TRANSACTION (0.3ms) BEGIN 3 Sample Exists? (0.6ms) SELECT 1 AS one FROM "samples" WHERE "samples"."url" = $1 LIMIT $2 [["url", "1"], ["LIMIT", 1]] 4 Sample Create (0.8ms) INSERT INTO "samples" ("url", "counter", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["url", nil], ["counter", 0], ["created_at", "2023-01-02 13:53:57.794657"], ["updated_at", "2023-01-02 13:53:57.794657"]] 5 TRANSACTION (0.3ms) ROLLBACK 6ActiveRecord::NotNullViolation: PG::NotNullViolation: ERROR: null value in column "url" of relation "samples" violates not-null constraint 7DETAIL: Failing row contains (10, null, 0, 2023-01-02 13:53:57.794657, 2023-01-02 13:53:57.794657). 8 9from /usr/local/bundle/gems/activerecord-7.0.4/lib/active_record/connection_adapters/postgresql_adapter.rb:768:in `exec_params' 10Caused by PG::NotNullViolation: ERROR: null value in column "url" of relation "samples" violates not-null constraint 11DETAIL: Failing row contains (10, null, 0, 2023-01-02 13:53:57.794657, 2023-01-02 13:53:57.794657).
  2. newメソッドに引数として渡した→反映されず

    ruby

    1[2] pry(main)> Sample.new(url: '1', counter: 20) 2=> #<Sample:0x00007fbbcdf95e30 id: nil, url: nil, counter: 0, created_at: nil, updated_at: nil>
  3. インスタンスを生成後、各項目に代入した→反映された

    ruby

    1[5] pry(main)> ins = Sample.new 2=> #<Sample:0x00007fbbcd888408 id: nil, url: nil, counter: 0, created_at: nil, updated_at: nil> 3[6] pry(main)> ins.url = 'sample' 4=> "sample" 5[7] pry(main)> ins.counter = 10 6=> 10 7[8] pry(main)> ins 8=> #<Sample:0x00007fbbcd888408 id: nil, url: nil, counter: 0, created_at: nil, updated_at: nil> 9[9] pry(main)>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

attr_accessor :url
が悪さしてるのでは無いかな。
消してみて

投稿2023/01/03 00:45

winterboum

総合スコア23282

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Hanbe.T

2023/01/03 04:43 編集

ありがとうございます。解決しました。
guest

0

※コメントにマークダウンが使用できなかったので。

ruby

1[1] pry(main)> ins = Sample.create(url: '1', counter: 10) 2 TRANSACTION (0.3ms) BEGIN 3 Good Exists? (0.8ms) SELECT 1 AS one FROM "samples" WHERE "samples"."url" = $1 LIMIT $2 [["url", "1"], ["LIMIT", 1]] 4 Sample Create (0.9ms) INSERT INTO "samples" ("url", "counter", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["url", "1"], ["counter", 10], ["created_at", "2023-01-03 03:48:22.770318"], ["updated_at", "2023-01-03 03:48:22.770318"]] 5 TRANSACTION (4.0ms) COMMIT 6=> #<Sample:0x00007f655fd2d9c8 id: 13, url: "1", counter: 10, created_at: Tue, 03 Jan 2023 03:48:22.770318000 UTC +00:00, updated_at: Tue, 03 Jan 2023 03:48:22.770318000 UTC +00:00>

accessorsを定義しなくても、デフォルトでaccessorsが生成される。
ActiveRecodが提供するaccessorsではsuperに対して処理をしているのに対して、Rubyが提供するaccessorsでは、自クラスに対してなので、ActiveRecordとしては処理されなかったのですね。

This would also define the following accessors: Product#name and Product#name=(new_name).
引用:https://api.rubyonrails.org/files/activerecord/README_rdoc.html

All column values are automatically available through basic accessors on the Active Record object, but sometimes you want to specialize this behavior. This can be done by overwriting the default accessors (using the same name as the attribute) and calling super to actually change things.

ruby

1class Song < ActiveRecord::Base 2 # Uses an integer of seconds to hold the length of the song 3 4 def length=(minutes) 5 super(minutes.to_i * 60) 6 end 7 8 def length 9 super / 60 10 end 11end

引用:Overwriting default accessors

投稿2023/01/03 04:44

編集2023/01/03 04:46
Hanbe.T

総合スコア36

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

winterboum

2023/01/03 05:17

accessor と言えば、まぁ似たような働きをしますが、意味合いも定義内容もかなり異なります。 attr_accessor :url は def url ; @url ; end def url=(arg) ; @url = arg ; end みたいな定義をしますが、database にある 項目 url に対して AR は @url ではなく self[ ] へのアクセスを定義します。(code未確認なのでちと違うかもですが) self[ ] は DB table との値のIFみたいなもの、、、 で、 これは class Sample < ApplicationRecord で定義されます。 そのあとで attr_accessor :url してるので AR による DB tableへのIF 定義 が壊されてしまった というわけです
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問