Skip to content

Conversation

@sana37
Copy link
Contributor

@sana37 sana37 commented Sep 23, 2020

Issue

概要

やりたいことボード(WishBoard)のusecase層以下を実装

タスク整理

  • 実装
  • テスト
  • mock?の作成

@sana37
Copy link
Contributor Author

sana37 commented Sep 23, 2020

テストとかまだ作れてませんが、とりあえず実装までは済んだのでいったんレビューお願いします!

@sana37 sana37 added the devlop 開発環境に関するタスク label Sep 23, 2020
Copy link
Contributor

@akubi0w1 akubi0w1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ざーっとコメントしましたー!何箇所か気になったところがあったので、みていただけると(ㅅ ;´꒳`;)
コード読みやすかったです、、、!(゚∀゚)

GetWishBoard(ctx context.Context, wishBoardID int, authID string) (*wishboard.Entity, error)
UpdateTitle(ctx context.Context, wishBoardID int, title, authID string) error
UpdateBackgroundImage(ctx context.Context, wishBoardID int, backgroundImage []byte, authID string) error
DeleteWishBoard(ctx context.Context, wishBoardID int, authID string) error
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ただの気づきです。。。
interactor内のメソッドの引数、確かにauthIDのがいいかもな...!わたしuserIDで実装してたけど、userIDってよく考えたら取れないのか...!!( ゚д゚)


func (i *interactor) CreateNewWishBoard(ctx context.Context, authID, title string, backgroundImage []byte) (*wishboard.Entity, error) {
// 空のタイトルは許容しない
if title == "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感想ですー!
この辺のバリデーションなのだけど、項目増えていくと膨れ上がっていくから、関数として出しちゃってもいいかも。
公開にする必要はないだろうから、validateTitle(title string) errorくらいな感じで。

GetByPK(ctx context.Context, masterTx repository.MasterTx, wishBoardID int) (*wishboard.Entity, error)
GetByOwner(ctx context.Context, masterTx repository.MasterTx, userID int) (wishboard.EntitySlice, error)
GetByMember(ctx context.Context, masterTx repository.MasterTx, userID int) (wishboard.EntitySlice, error)
UserBelongs(ctx context.Context, masterTx repository.MasterTx, userID, wishBoardID int) (bool, error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感想です!
boolが返ってくるメソッドの名前は、IsXXXのが明確でいいかな、と思ったりなど。。。
IsUserBelongedとかかな...英語力...(ㅅ ;´꒳`;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なるほど…
IsUserMemberでいこうかと思う!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

わざわざ主語書かなくてもいいだろうってことでIsMemberになりました!


type Repository interface {
Insert(ctx context.Context, masterTx repository.MasterTx, userID, wishBoardID int) error
SelectByUserIDAndWishBoardID(ctx context.Context, masterTx repository.MasterTx, userID, wishBoardID int) (bool, error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感想です〜
ここのメソッド、boolが返ってくるんで、名前がIsXXXの方が落ち着くかも

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

たしかに変だよな〜
シンプルにExistsとかにしようかな

return nil, werrors.FromConstant(err, werrors.ServerError)
}

bis := make([]int, 0, 4)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここの、3つめの引数の4って固定値、特に決まった値ってないはずなので、無理にmakeしなくていいかも!
rowsから件数取れんから、bis := []int{}でいいかなーと思う!

}

// 現在時刻を取得
now := time.Now()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感想ですー
時刻の取得なんだけど、DBアクセス系の処理じゃないので、serviceとかでやった方がいいかも?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

了解!

return nil, werrors.FromConstant(err, werrors.ServerError)
}

bs := make(wishboard.EntitySlice, 0, 4)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここの3つめの引数、固定値じゃない方がよいかもですー!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

以下、複数同じところがあるので、同じくって感じです!

if err != nil {
if err == sql.ErrNoRows {
// 見つからなかったから空リストを返す
return []*wishboard.Entity{}, nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここのreturnで返すの、nil, nilで良いと思う!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

そういえばgoの配列型ってnilでも空配列みたいな使い方できるんだっけ
了解、nilにしておく〜

ErrorCode: http.StatusForbidden,
ErrorMessageJP: "ボードへのアクセスが許可されていません",
ErrorMessageEN: "you don't have access to wish_board",
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ナイス定義...!٩( 'ω' )و

@sana37
Copy link
Contributor Author

sana37 commented Sep 26, 2020

修正しました!

Copy link
Contributor

@TakumaKurosawa TakumaKurosawa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

いったんコメントしました!

type Interactor interface {
CreateNewWishBoard(ctx context.Context, authID, title string, backgroundImage []byte) (*wishboard.Entity, error)
GetMyWishBoards(ctx context.Context, authID string) (wishboard.EntitySlice, error)
GetWishBoard(ctx context.Context, wishBoardID int, authID string) (*wishboard.Entity, error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

今回の実装では必要ないので消して欲しい!

GetByPK(ctx context.Context, masterTx repository.MasterTx, wishBoardID int) (*wishboard.Entity, error)
GetByOwner(ctx context.Context, masterTx repository.MasterTx, userID int) (wishboard.EntitySlice, error)
GetByMember(ctx context.Context, masterTx repository.MasterTx, userID int) (wishboard.EntitySlice, error)
IsUserMember(ctx context.Context, masterTx repository.MasterTx, userID, wishBoardID int) (bool, error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
IsUserMember(ctx context.Context, masterTx repository.MasterTx, userID, wishBoardID int) (bool, error)
IsMember(ctx context.Context, masterTx repository.MasterTx, userID, wishBoardID int) (bool, error)

// 現在時刻を取得
now := time.Now()

b := &wishboard.Entity{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bだとわかりづらいので、newBoardのように変数見ただけで何を表しているかわかるような名前にしてください!
他のところも同様!!

@TakumaKurosawa TakumaKurosawa changed the base branch from develop to feat/3/base September 27, 2020 07:28
@sana37
Copy link
Contributor Author

sana37 commented Sep 27, 2020

指摘のあった部分、修正しました!

Copy link
Contributor

@TakumaKurosawa TakumaKurosawa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

コメントした!
これが修正できたらまた見るのでレビュー依頼よろです!

Comment on lines 220 to 228
func validateTitle(ctx context.Context, title string) error {
if title == "" {
err := errors.New("title is empty")
tlog.PrintErrorLogWithCtx(ctx, err)
return werrors.FromConstant(err, werrors.BadRequest)
}

return nil
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これくらいの行数であれば、Privateメソッドに切り出す必要ないかなー。
バリデーションはその場で何をしているのか確認したかったりもするし、よっぽどメソッド切り分けしないイメージ。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これはあくびとも話したんだけど、タイトルのバリデーション項目が増えたときのことを考えると
切り出した方がいいかな、って思った

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sana37 cc: @akubi0w1
増えたら増えた時に考えたいのと、validateTitleのなかでいろいろなバリデーションが隠蔽化されていると使う方も怖くなると思うし、ユースケースごとにバリデーションを使い分けたいとなった時に、謎のバリデーション関数2みたいなのが出来上がる危険性があるので、もし分けるとしても、 ngWordCheckとかisEmptyとかみたいな単位で一個一個分けて欲しいかな。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

了解!切り出さない方向で修正するね

Comment on lines 40 to 42
if err := validateTitle(ctx, title); err != nil {
return nil, werrors.Stack(err)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

privateメソッドに切り出さない方が良さそう。

Comment on lines +57 to +58
// TODO: 招待URLの自動生成
inviteURL := "hoge"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uuidで自動生成するだけやと思うから、ここで実装しちゃっても良いかもね?w

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あと、実装する場合は、 wishBoardService.CreateInviteURLみたいにService層の実装として欲しい!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

service層で実装する了解!
一応、仕様がはっきり決まるまでは実装しないでおく!
あと思ったんだけど、grpcで招待URLってどうやって使うんだろう…?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あと思ったんだけど、grpcで招待URLってどうやって使うんだろう…?

招待を受け付けるエンドポイントをRESTで用意してあげる必要があるね!

Comment on lines 50 to 62
row := tx.QueryRow(`
SELECT id FROM users_wish_boards WHERE user_id = ? AND wish_board_id = ?
`, userID, wishBoardID)

var i int
err = row.Scan(&i)
if err != nil {
if err == sql.ErrNoRows {
// 見つからなければfalseを返す
return false, nil
}
return false, werrors.FromConstant(err, werrors.ServerError)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

結局プログラムでやるのであれば、Service層で判定して欲しいかなー。
もしくは、関数名通り、MySQLのExists関数を使ってあげるかやなー。
https://qiita.com/mtanabe/items/5b8171a9d3ad9e559783

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Existsなんてものがあったのね!
便利そうだから使う!

return true, nil
}

func (r *repositoryImpliment) SelectByUserID(ctx context.Context, masterTx repository.MasterTx, userID int) ([]int, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SelectByUserIDという関数名から、 []intが返ってくるとは思わなくて驚きそうだから、再設計をしてみて!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

目的語ちゃんと足しとくね

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

devlop 開発環境に関するタスク

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants