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

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

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

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

Q&A

解決済

1回答

385閲覧

railsのform_forをモデルの一部の要素だけ作成したい

sakas1231

総合スコア42

Ruby on Rails

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

0グッド

1クリップ

投稿2017/10/17 06:37

編集2017/10/17 20:40

今、Ruby on Railsで、Userモデルに:name, :email, :password, :password_confirmation, :budgetの5つが入っています。

これら五つのうち、nameとemailとbudgetのみのテキストフィールドを表示させるページ( user/:id/edit )を作成して、form_forでupdateさせたいと思っています。( 残りのpasswordとpassword_confirmationはこのページでは変更を加えないということです )

そこで、以下のようなform_forを作り、controllerのupdateアクションにいかせようと思ったのですが、どうも正常にupdateされません。( updateのflash[:notice]側のelseにいってしまう )

原因はedit.html.erb内でpasswordとpassword_confirmationについて明示していないのでuser_paramsの値が

"user"=>{"name"=>"after_hoge", "email"=>"afterhoge@example.com", "budget"=>"10000"}

になってしまっているということがわかったのですが、それに対する対処法がわからないです。

どなたかご教授願えますでしょうか?

edit.html.erb

<div class="well col-md-6 col-md-offset-3"> <!--small>初めての方はアカウントを<%= link_to "新規作成", signup_path %>してください</small--> <%= form_for(@user) do |form| %> <div class="field"> <%= form.label :name %> <%= form.text_field :name, id: :user_name, class: 'form-control'%> </div> <div class="field"> <%= form.label :email %> <%= form.text_field :email, id: :user_email, class: 'form-control' %> </div> <div class="field"> <%= form.label :budget ,'今月の予算' %> <%= form.number_field :budget, id: :user_budget, class: 'form-control' %> </div> <!--div class="field"> <%= form.label :exp %> <%= form.number_field :exp, id: :user_exp %> </div> <div class="field"> <%= form.label :level %> <%= form.number_field :level, id: :user_level %> </div--> <div class="actions text-center"><br> <%= form.submit '登録', class: 'btn btn-primary' %> </div> <% end %>

updateアクション

def update respond_to do |format| if @user.update(user_params) flash[:success] = "User was successfully updated." format.html { redirect_to @user } format.json { render :show, status: :ok, location: @user } return redirect_to user_url @user else #puts(user_params) flash[:notice] = "User updating was failed." format.html { render :edit } format.json { render json: @user.errors, status: :unprocessable_entity } end end

[修正内容]
モデル側のバリデーションとのことで、user.rbとuser_test.rbを載せさせていただきます。
ちなみにreils testは通ってます(全然テスト書いていないのであたりまえかもしれないですが)
user.rb

class User < ApplicationRecord has_many :books, dependent: :destroy before_save { self.email = email.downcase } validates :name, presence: true, length: { maximum: 50 } VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+.[a-z]+\z/i validates :email, presence: true, length: { maximum: 255 }, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false } validates :budget, numericality: true validates :password, presence: true, length: { minimum: 6 } has_secure_password # 与えられた文字列のハッシュ値を返す def User.digest(string) cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost BCrypt::Password.create(string, cost: cost) end # ランダムなトークンを返す def User.new_token SecureRandom.urlsafe_base64 end end

user_test.rb

require 'test_helper' class UserTest < ActiveSupport::TestCase # test "the truth" do # assert true # end #@user.validはバリデーションを通るとture,invalidだと逆に通らないとtureになる def setup @user = User.new(name: 'foobar', email: 'sample@example.com', budget: 1000, exp:0, level:0, password:'foobar', password_confirmation: 'foobar') end #正しいユーザーはバリデーションを通る test "user validates all" do assert @user.valid? end #名前が50文字以上だと通らない test "user validates name" do @user.name = "a" * 51 assert @user.invalid? end #emailは正しいものを test "user validates email" do @user.email = "a" assert @user.invalid? end #budgetは整数で test "user validates budget" do @user.budget = "100a" assert @user.invalid? end #passwordは6文字以上 test "user validates password" do @user.password = "a" * 5 @user.password_confirmation = @user.password assert @user.invalid? end #passwodとpassword_confirmationは同じでなくてはいけない test "user validates passowrd = password_confirmation" do @user.password = "difference" assert @user.invalid? end #登録されているemailは使えない(user.ymlのoneがtest@sample.com) test "user validates email exists" do @user.email = "test@sample.com" assert @user.invalid? end end

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

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

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

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

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

maisumakun

2017/10/17 06:48

モデルの側でのバリデーションが影響していることも考えられますので、モデルのコードも載せていただけませんか?
sakas1231

2017/10/17 20:41

回答ありがとうございます。 user.rb.とuser_test.rbを編集で追加させていただきました。
kenchankunsan

2017/10/21 10:18

else句の中で、putsやRails.logger等を使って @user.errorsの中身を表示されると何か入っていますか?
sakas1231

2017/10/24 07:20

返信遅くなってしまい申し訳有りません。 @user.loggerには何も入っていませんでした... password以外のformをhiddenにするのはできるのですが、passwordだけhiddenにすることができない感じです
sakas1231

2017/10/24 07:22

putsを使ってeditアクションからupdateを通してshowに戻る時に、showアクションの段階で@user.passwordにnullが入っている状態でした。 passwordはdbにハッシュにされて保存されているのでhiddenで直接@user.passwordを代入することはできないということでしょうか?
guest

回答1

0

ベストアンサー

公開してもらったコードの以下のputs(user_params)の出力が以下のようになっているということでしょうか?

"user"=>{"name"=>"after_hoge", "email"=>"afterhoge@example.com", "budget"=>"10000"}

ruby

1 def update 2 respond_to do |format| 3 if @user.update(user_params) 4 flash[:success] = "User was successfully updated." 5 format.html { redirect_to @user } 6 format.json { render :show, status: :ok, location: @user } 7 return redirect_to user_url @user 8 else 9 #puts(user_params) # ここの出力 10 flash[:notice] = "User updating was failed." 11 format.html { render :edit } 12 format.json { render json: @user.errors, status: :unprocessable_entity } 13 end 14 end

もしそうなのであれば、updateの引数に渡すべきは以下のような形のhashになるので、

{"name"=>"after_hoge", "email"=>"afterhoge@example.com", "budget"=>"10000"}

updateに渡す部分を以下のように書くと更新できるのではないでしょうか?

ruby

1@user.update(user_params[:user])

質問への追記にあった「passwordが空になっているからではないか?」というのは、ハッシュのキー自体が無い場合は何も更新が行われないので、問題無いかと思います。

投稿2017/10/26 11:40

kenchankunsan

総合スコア240

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問