Rails×Reactでアフィリエイトシステムを作る
以前携わった案件でアフィリエイト機能を付け足そうか議論になったことがあり、(結局はやらなかった)それを思い出したので実装してみました。
ちなみにアフィリエイトとはAmazonや楽天で販売されている商品を自身のSNSやメディアなどに掲載し、そこから発生した売上の一部を還元されるという仕組みです。代表的な例としてAmazonアソシエイトや楽天アフィリエイトなどがあります。
皆さんがブログなどでよく見る商品のバナー広告などのことです。アフィリエイターはアフィリエイトリンクをブログなどに差し込んでそのリンクから発生したうりあげの一部がアフィリエイターに還元されます。
※ 今回はcorsの設定やユーザーの認証周りなど色々省略しているので、そのままだと動かないかもしれませんがアフィリエイトの簡単な仕組みの紹介なので今回はご容赦ください🙇♂️
ちなみに筆者は認証周りのライブラリはdevice_token_auth、deviseを使用しました。
フロントエンド
import Cookies from 'js-cookie';
~ 中略 ~
React.useEffect(() => {
if (!ref || Cookies.get('_affiliater_id')) return;
Cookies.set('_affiliater_id', ref, { expires: 30 });
});
例えばhttps://example.com/?ref=[紹介者ID] というリンクをブログから踏んできたユーザーの端末のcookieに_affiliater_idに紹介者IDがセットされます。
import axios from 'axios';
import Cookies from 'js-cookie';
type SignUpParams = {
email: string;
password: string;
}
const signUp = async (params: SignUpParams) => {
const response = await axios.post('/api/auth', params);
if (Cookies.get('_affiliater_id')) {
await registerAffiliater({identifier: Cookies.get('_affiliater_id')})
}
return response;
}
const registerAffiliater = async (params: { identifier: string }) => {
const response = await axios.post('/api/users/affiliates', params);
return response;
};
フォームからemailとpasswordを入力してサインアップ後、Cookieに_affiliater_idが存在する場合、registerAffiliater関数が実行されアフィリエイターが登録される仕組みです。
バックエンド
モデル設計
User
※ 本来はpasswordはハッシュ化したものを保存するべきだが今回は割愛。
class CreateUsers < ActiveRecord::Migration[6.1]
def change
create_table :users do |t|
t.string :email
t.string :password
t.string :identifier
t.timestamps
end
end
end
class User < ApplicationRecord
has_one :affiliater, class_name: 'Affiliate', foreign_key: 'affiliated_id', dependent: :destroy
has_one :affiliate_user, through: :affiliater, source: :affiliater
has_many :affiliated, class_name: 'Affiliate', foreign_key: 'affiliater_id', dependent: :destroy
has_many :affiliated_users, through: :affiliated, source: :affiliated
end
紹介者は一人にすべきなので、affiliaterはhas_oneを使いました。affiliate_user、affiliated_usersでユーザーを直接参照できるように。
Affiliate
class CreateAffiliates < ActiveRecord::Migration[6.1]
def change
create_table :affiliates do |t|
t.references :affiliater, null: false, foreign_key: { to_table: :users }
t.references :affiliated, null: false, foreign_key: { to_table: :users }
t.timestamps
end
end
end
class Affiliate < ApplicationRecord
belongs_to :affiliater, class_name: 'User'
belongs_to :affiliated, class_name: 'User'
validates :affiliater_id, uniqueness: { scope: :affiliated_id }
validate :cannot_be_affiliater_mine
def cannot_be_affiliater_mine
return unless affiliated == affiliater
errors.add(:base, '自分のアフィリエイターにはなれません')
end
end
Affiliateモデルにはaffiliaterとaffiliatedが一致するパターンとaffiliterとaffiliatedが同ユーザーである場合にバリデーションを設定しました。
コントローラー
module Api
class AffiliatesController < ApplicationController
before_action :find_affiliter, only: %i[create]
def create
if @affiliater
affiliate = Affiliate.create(affiliater: @affiliater, affiliated: current_user)
render json: {data: affiliate, message: "成功しました", status: 200}
else
render json: {data: nil, message: "失敗しました", status: 500}
end
end
private
def find_affiliater
@affiliater = User.find_by(identifier: params[:identifier])
end
end
end
ルーティング
Rails.application.routes.draw do
namespace :api do
resources :users do
collection do
resources :affiliates, only: %i[create]
end
end
end
end
以上です、ありがとうございました!
Author And Source
この問題について(Rails×Reactでアフィリエイトシステムを作る), 我々は、より多くの情報をここで見つけました https://qiita.com/kenshin_kenboo/items/f06762281ca241e2f948著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .