5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Rails】find_or_initialize_byメソッドを使ってインスタンスを作成する時のポイント

Last updated at Posted at 2019-04-14

現在、amazonAPIを利用した口コミの共有サービスを作成中です。

その中で、「商品を検索し表示させる」という処理があるのですが、その際に役立ったfind_or_initialize_byメソッドについて簡単に整理します。

#find_or_initialize_byメソッドとは

find_or_initialize_byメソッドとは、条件に合致したインスタンスがデータベースに保存されているかどうかをチェックしています。

この際、

  • データベースに保存されている場合はfindメソッド
  • データベースに保存されていない場合は'new'メソッド

として、インスタンスの状況によって適用されるメソッドが異なることがポイントです。インスタンスが保存されている場合、findメソッドが適用されるのでインスタンスに保存済みのデータ(idなど)を含めることができます。

インスタンス = persisted?インスタンス = new_record?でデータベースの保存状況を真偽値で取得できます。

#find_or_initialize_byメソッドの使い道

前述の通り、find_or_initialize_byは条件分岐がポイントとなるので、データベースの保存状況でインスタンスに変化を与えたい場合に有用となります。

例えば私の場合ですと、APIから商品データを取得し一覧表示しています。

その際に、データベース保存済みなら「商品削除ボタン」を表示、データベースに保存していない新規のインスタンスなら「商品登録ボタン」を表示したいケースで、find_or_initialize_byを使用しています。

products_controller.rb
def create
  @product = Product.find_or_initialize_by(asin: params[:product_asin])
  unless @product.persisted?
    # @product が保存されていない場合、先に @product を保存する
    products = Amazon::Ecs.item_lookup(
      params[:product_asin],
      response_group: 'Medium',
      country: 'jp'
    )

    products.items.each do |item|
      @product = Product.new(
        title: item.get('ItemAttributes/Title'),
        image_url: item.get('LargeImage/URL'),
        url: item.get('DetailPageURL'),
        asin: item.get('ASIN'),
        brand_amazon_name: item.get('ItemAttributes/Brand'), 
        price: item.get('OfferSummary/LowestNewPrice/Amount'), 
      )
    @product.save
    end
  end  
end
_products.html.erb
<!--商品登録削除ボタン-->
<div class="buttons text-center">
<% if product.persisted? %>
  <%= form_tag(product_path(product.id), method: :delete) do %>
    <%= hidden_field_tag :product_id, product.id %>
    <%= submit_tag '削除', class: 'btn btn-danger' %>
  <% end %>
<% else %>
  <%= form_tag(products_path) do %>
    <%= hidden_field_tag :product_asin, product.asin %>
    <%= submit_tag '登録', class: 'btn btn-primary' %>
  <% end %>
<% end %>

#(+α)find_or_create_byメソッドについて

find_or_create_byメソッドは、find_or_initialize_byと似た内容のメソッドなので、今後のために簡単に整理。

条件に合致したインスタンスがデータベースに保存されているかどうかをチェックしている点は、両者とも同じです。

その際に、find_or_create_byメソッドは、

  • データベースに保存されている場合はfindメソッド
  • データベースに保存されていない場合は**'create'**メソッド

となることがポイントです。「データベースに保存されていない場合は**'create'**メソッド」となるのですね。

条件に合致した情報をゴリゴリとデータベースに保存していくというケースに適しているのでしょう。

#まとめ

find_or_initialize_byメソッドは、「APIを利用して情報取得→整形しインスタンス作成」のようなケースで役立つことがわかりました。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?