一部のモデルにはcreateステートメントがありますが、レコードがすでに存在するかどうかに関係なく、結合テーブル内にレコードが作成されます。
私のコードは次のようになります:
@user = User.find(current_user)
@event = Event.find(params[:id])
for interest in @event.interests
@user.choices.create(:interest => interest, :score => 4)
end
問題は、何があってもレコードを作成することです。レコードが存在しない場合にのみレコードを作成します。レコードが存在する場合は、見つかったレコードの属性を使用して、1を加算または減算します。
私は周りを見回してきましたが、find_or_create_by
。レコードが見つかるとどうなりますか?現在の:score
属性と1を追加します。
id
で検索または作成できますか?探しているモデルはid
外部キーとスコア属性のみを持つ結合モデルであるため、どの属性で検索できるかわかりません。
私は試した
@user.choices.find_or_create_by_user(:user => @user.id, :interest => interest, :score => 4)
しかし得た
未定義のメソッド
find_by_user
私は何をすべきか?
Choice
モデルにuser_id
(ユーザーに関連付ける)とinterest_id
(インタレストに関連付ける)があるとすると、次のようなことがうまくいくはずです。
@user = User.find(current_user)
@event = Event.find(params[:id])
@event.interests.each do |interest|
choice = @user.choices.find_or_initialize_by_interest_id(interest.id) do |c|
c.score = 0 # Or whatever you want the initial value to be - 1
end
choice.score += 1
choice.save!
end
いくつかのメモ:
user_id
に属するchoices
のみをフェッチするようにすでにRailsに指示しているため、find_or_*_by_*
に@user
列を含める必要はありません。find_or_initialize_by_*
と同じfind_or_create_by_*
を使用していますが、initialize
は実際にはレコードを作成しないという大きな違いがあります。これは、Model.new
ではなく、Model.create
に似ています。c.score = 0
を設定するブロックは、レコードにnotが存在する場合にのみ実行されます。choice.score += 1
は、レコードが存在するかどうかに関係なく、レコードのスコア値を更新します。したがって、デフォルトのスコアc.score = 0
は、初期値から1を引いた値になります。choice.save!
はレコードを更新する(既に存在する場合)か、開始されたレコードを作成します(存在しない場合)。my_class = ClassName.find_or_initialize_by_name(name)
my_class.update_attributes({
:street_address => self.street_address,
:city_name => self.city_name,
:Zip_code => self.Zip_code
})
find_or_create_by_user_id
よく聞こえる
また、Railsでは次のことができます:
@user.choices.where(:user => @user.id, :interest => interest, :score => 4).first_or_create
Rails 4を使用している場合は、これまでのようなFinderメソッドが作成されるとは思わないため、find_or_create_by_userは作成されません。代わりに、次のようにします。
@user = User.find(current_user)
@event = Event.find(params[:id])
for interest in @event.interests
@user.choices.find_or_create_by(:interest => interest) do |c|
c.score ||= 0
c.score += 1
end
end
In Rails 4find_or_create_by
を使用してオブジェクトを取得し(存在しない場合は作成されます)、次にupdate
を使用してレコードを保存または更新します。更新メソッドは、レコードが存在しない場合はそれを保持し、それ以外の場合はレコードを更新します。
例えば
@edu = current_user.member_edu_basics.find_or_create_by(params.require(:member).permit(:school))
if @edu.update(params.require(:member).permit(:school, :majoy, :started, :ended))