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

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

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

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

Ruby on Rails

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

Q&A

1回答

1624閲覧

【Rails】friendly_idと:id代わりのランダム文字列の併用

Romay

総合スコア40

Ruby

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

Ruby on Rails

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

0グッド

0クリップ

投稿2019/05/06 23:24

前提・実現したいこと

Ruby 2.4.5
Rails 4.2.8
本番環境:heroku postgreSQL
開発環境:mySQL

friendly_idを利用し、サイト名/users/:idをサイト名/(好きな文字列)にユーザー自身で設定できるようにしています。
friendly_idについて

しかし、ユーザー登録時にはfrinedly_idを設定していないため、デフォルトだと、サイト名/users/1のように連番になります。
これを防ぐために(ユーザビリティ的によくない)、サイト名/users/(ランダム文字列)をデフォルトにしようとしています。

そこで、urlランダム文字列の実装とfriendly_idのGemがバッティングしているようでエラーが出ています。

Userテーブルに、url_tokenというカラムを追加しランダムな文字列を追加します。
それを:idの連番の代わりにデフォルトのルーティングとして用いるということです。

発生している問題・エラーメッセージ

エラー文

ruby

1undefined method `type' for :string:Symbol 2 3 def correct_user 4 user = User.friendly.find_by(url_token: params[:url_token]) #ここがダメ 5 if current_user != user 6 redirect_to root_path 7 end 8 end

該当のソースコード

user_controller

ruby

1 def show 2 #@user = User,friendly.find(params[:id])もともとこれ 3 @user = User.friendly.find_by(url_token: params[:url_token]) 4 @items = @user.items 5 @image = Image.includes(:user).order("created_at").last 6 end

ルーティング
Routes.rb

ruby

1 devise_scope :user do 2 get '/:id/' => 'users#show', as: 'show', param: :url_token #param以下を追加 3 get '/:id/edit' => 'users#edit', as: 'edit', param: :url_token #param以下を追加 4 put '/:id/' => 'users#update', as: 'update', param: :url_token #param以下を追加 5 get '/users/sign_out' => 'devise/sessions#destroy' 6 end

Userモデル
User.rb

ruby

1# url_tokenに対する設定を追加 2 before_save :generate_url_token 3 attribute :url_token, :string, default: SecureRandom.hex(10) 4 5#(省略) 6 7 #friendly_url 8 include FriendlyId 9 friendly_id :friendly_url 10 11 validates :friendly_url, length: { in: 3..20 }, 12 uniqueness: true, #一意性 13 format: { with: /\A[\w@-]*[A-Za-z][\w@-]*\z/ }, 14 # on: :friendly_url_user #登録時に入力必要なし 15 allow_nil: true #無入力許可 16 17 # url_tokenに対してのvalidation 18 validates :url_token, presence: true, uniqueness: true 19 def to_param 20 url_token 21 end 22 23#ログイン時にnillの場合生成する 24 def generate_url_token 25 if url_token.nil? 26 self.url_token = SecureRandom.hex(10) 27 self.save 28 end 29 end

試したこと

friendly_idのGemが便利な分、裏側でどう動いているのかが分かっていないのが現状です。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

siruku6

2019/05/14 22:42 編集

friendly_id については使ったことがないのでよく分かりませんが、Userテーブルにurl_token列を追加したのであれば、 User.find_by(url_token: params[:url_token]) で取得できそうな気がします。 friendlyの動作が消えてしまうかもしれませんが。。。。これは試してみましたか?
guest

回答1

0

ruby

1user = User.friendly.find_by(url_token: params[:url_token]) #ここがダメ

ruby

1user = User.friendly.find_by(url_token: params[:id]) #ここがダメ

これで動かないですか?

投稿2019/05/10 02:30

odyu

総合スコア548

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

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

Romay

2019/05/10 03:59

コメントありがとうございます。うまくいかないです...。url_tokenというカラムをUserモデルに追加したのでこれでfind_byしたいのですが、friendly_idの仕様的には、idじゃないとうまくいというジレンマがあります...。
odyu

2019/05/10 04:33

friendly_idのgemのコードみました。 全体的にちょっと違和感がありますが class User friendly_id :friendly_url これって friendly_id :url_token ではないですか? あと User.friendly.find_by これは User.friendly.find ではないですか? https://github.com/norman/friendly_id/blob/master/lib/friendly_id/finder_methods.rb#L18-L25 ActiveRecrodのfindとは別のmethodですね。 undefined method `type' for :string:Symbol このエラーはpolymorphicでのエラーっぽいですね url_tokenとfriendly_urlの違いは何でしょうか?
Romay

2019/05/10 06:06

ありがとうございます。実は、friendly_idを使って実装し正常に動いているところに、url_tokenを追加した形なのです。friendly_idによって、ユーザーが任意に サイト名/以下のURLを設定できますが、ユーザー登録時には未設定のため、Rails特有の サイト名/users/1のように連番で表示されます。これを登録時の時点でランダムな文字列、サイト名/dhuhuef242fwにするため、url_tokenというカラムを追加しました。 class User frindly_id: friendly_url の部分は、friendly_urlとして扱えるようにしているだけです。 User.friendly_findのところは、もともと「find」のところを、find_byにしないとurl_tokenでは使えないそうで変更をしました。 url_tokenとfriendly_urlの違いは、url_tokenはユーザー登録時に発行するランダム文字列で、friendly_urlは、ユーザーが任意に何回でも設定変更できる文字列です。 おそらく、このfriendly_idと併用するという見通し自体が悪いのかとは思うのですが、やりたいことの実現がこの方法以外で思いつかず。。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問