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

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

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

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

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Active Record

Active Recordは、一つのオブジェクトに対しドメインのロジックとストレージの抽象性を結合するデザインパターンです。

Q&A

2回答

5639閲覧

レコードがすでに存在する場合は、作成せずに更新したい

jamsyrup

総合スコア13

Ruby

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

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Active Record

Active Recordは、一つのオブジェクトに対しドメインのロジックとストレージの抽象性を結合するデザインパターンです。

1グッド

1クリップ

投稿2016/05/29 21:23

作家、作品、フレーズを投稿するフォームがあり、ユーザーがフォームにそれらを投稿する際、
すでにその作家が存在する場合、
・その作家を新規作成せずに、その作品だけを新規作成。
・このとき、もし作品も存在していたら、作品を新規作成せずに、そのフレーズのみを新規作成。

以上のことがしたいのですが、
現状、
①既存の作家に新規の作品をひもづける。
②既存の作家の、既存の作品に新規のフレーズをひもづける。
というところまではできているのですが、
②をする際に、新規に、既存の名前と同じ作品が登録されてしまいます。
これを解決するにはどうしたらよいでしょうか?

以下に、該当する箇所のコードを記載いたします。

class AuthorsController < ApplicationController def new @author = Author.new @writing = @author.writings.build @word = @writing.words.build(author_id: @author.id) end def create @author = Author.find_or_initialize_by(name: params[:author][:name]) @author.update_attributes(author_params) end private def author_params params.require(:author).permit(:id, :name, writings_attributes: [:id, :title, words_attributes: [:id, :content, :author_id]]) end

作家、作品、フレーズのモデル

class Author < ActiveRecord::Base has_many :writings has_many :words, through: :writings accepts_nested_attributes_for :writings class Writing < ActiveRecord::Base belongs_to :author, :autosave => true has_many :words accepts_nested_attributes_for :words def autosave_associated_records_for_author if new_author = Author.find_by(name: author.name) self.author = new_author else self.author.save! end end class Word < ActiveRecord::Base belongs_to :writing, :autosave => true has_one :author, through: :writing def autosave_associated_records_for_writing if new_writing = Author.find_by(name: author.name).writings.find_by(title: writing.title) self.writing = new_writing else self.writing.save! end end end

よろしくお願いいたします。

Fasahina👍を押しています

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

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

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

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

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

guest

回答2

0

参考情報:

...
検索条件を指定して初めの1件を取得し、1件もなければ作成(find_or_create_by)
...

...
なるほどidの値も含めてfirst_or_createを呼べばいいのか。
ってこれならfirst_or_createじゃなくてfind_or_createでも一緒では、って思ったら、どうやらfind_or_createはdeprecateになるらしい。
...

投稿2016/05/29 22:12

katoy

総合スコア22324

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

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

0

  1. uniqeキーを設定する
  2. first_or_create メソッドで取得する

詳細はググってくださいませ。

投稿2016/05/29 21:35

sokha

総合スコア216

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

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

jamsyrup

2016/05/30 10:23

uniqueキーを設定した場合、 たとえば、すでに author:「川端康成」、writing:「雪国」が登録されていて、 「川端康成」の「雪国」の別のフレーズを登録しようとしたとき、 not uniqueになります。 このとき、そのフレーズを、すでに存在している「雪国」にひもづけて、新規のレコードを作成しなければ、not uniqueにはならないと思うのですが、それをするにはどうすればよいでしょうか? よろしくお願いします。 また、find_or_createについては、authorのレコードについては適用していますが、accepts_nested_attributes_forのwritingにはどのように適用できますでしょうか? 重ねてお願いします。
sokha

2016/06/06 03:31

回答が遅くなり申し訳ありません。 なるほど、ちょっと複雑ですね。 同じ要件を果たすために、以下のようなテーブル構造の方がいいかと思いました。 ``` --- id, author_name, writings, words --- find_or_create( author_name, writings, words) ``` もしくは ``` - authors id , name - writings id, name - words id, authors_id, writings_id, word find_or_create( aurhors_id, wrtings_id, word ) ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問