Chino-s / travel_c

0 stars 0 forks source link

管理画面のテストを実装する #31

Open Chino-s opened 7 years ago

Chino-s commented 7 years ago

@takumiyamamoto

  def update
    @country = Country.find(params[:id])
      if @country.update_attributes(:name, :capital)
        redirect_to [:admin, @country], notice: 'Country was successfully updated.'
      else
        render 'edit'
      end
  end

  def destroy
    @country = Country.find(params[:id])
    @country.destroy
    redirect_to [:admin, @country], notice: 'Country deleted.'

  end

こういうことでしょうか? これを実行したところ、このようなエラーが出てしまいました。 カラム指定の方法が悪いのでしょうか?

2017-06-14 11 12 07

takumiyamamoto commented 7 years ago

こんな書き方はしないよ

@country.update_attributes(:name, :capital)

こうなるはず

@country.update_attributes(name: "変更する内容")

これの違いはわかる??

name:

:name
Chino-s commented 7 years ago

@takumiyamamoto

spainの国名をtaiwanに変更してみたんですが、 変更されずにSuccessfullyと出てしまいました。 SQlite3も確認したんですが、 更新せれていませんでした。

  def update
    @country = Country.find(params[:id])
      if @country.update_attributes(params[:name])
        redirect_to [:admin, @country], notice: 'Country was successfully updated.'
      else
        render 'edit'
      end
  end
2017-06-14 13 41 20 2017-06-14 13 40 44 2017-06-14 13 41 09
takumiyamamoto commented 7 years ago

これがダメ

@country.update_attributes(params[:name])
これは文字列が入っている入れ物でしかない

params[:name]

やってるのはこれと同じことになる
@country.update_attributes("台湾")

どこのからむを変更するっていうキーの情報がない

takumiyamamoto commented 7 years ago

後はここを見ておいて

http://qiita.com/metheglin/items/db595d972df99b3849c2

Chino-s commented 7 years ago

@takumiyamamoto

仕組みはわかったんですが、 <%= f.text_field :name %>テキストボックスに入力された 文字列をどのように name: に入れるんですか?

参考サイト調べて見たんですが、 どこも({ name: "Isaac Newton", age: 35 })このように代入方法で行なっているため、、、

takumiyamamoto commented 7 years ago

@Chino-s

以下で取れると思うよ

params[:name]

こんな感じでテストの時だけプログラムに入れておくと パラメータの中にどんなものが入ってるのかをコンソールのログでみれたりするよ

puts params

コントローラーに書くならこんな感じかな

@country.update_attributes(name: params[:name])
Chino-s commented 7 years ago

@takumiyamamoto

こういうことですよね?

def update
    @country = Country.find(params[:id])
      if @country.update_attributes(params[:name])
        redirect_to [:admin, @country], notice: 'Country was successfully updated.'
      else
        render 'edit'
      end
  end
takumiyamamoto commented 7 years ago

@Chino-s

この書き方ダメ(本日2回目)

@country.update_attributes(params[:name])
Chino-s commented 7 years ago

@takumiyamamoto

params[:name] これで取れるんですよね?

Chino-s commented 7 years ago

@takumiyamamoto

  def update
    @country = Country.find(params[:id])
      if @country.update_attributes(name: params[:name])
        redirect_to [:admin, @country], notice: 'Country was successfully updated.'
      else
        render 'edit'
      end
  end

こういうことですか?

takumiyamamoto commented 7 years ago

@Chino-s それで動かしてみ

Chino-s commented 7 years ago

not nullのエラーになってしまいました。

2017-06-14 14 52 31
takumiyamamoto commented 7 years ago

コントローラの中にこれを入れて パラメータの中にどんなものが入っているのかをコンソールのログを見て確認する

puts params
Chino-s commented 7 years ago

@takumiyamamoto

  def update
    @country = Country.find(params[:id])
      if @country.update_attributes(name: params[:name])
        redirect_to [:admin, @country], notice: 'Country was successfully updated.'
        puts params
      else
        render 'edit'
      end
  end

こういうことですよね?

Chino-s commented 7 years ago

@takumiyamamoto

  def update
    @country = Country.find(params[:id])
      if @country.update_attributes(name: params[:name])
        redirect_to [:admin, @country], notice: 'Country was successfully updated.'
        logger.debug(puts params[:name])
      else
        render 'edit'
      end
  end
Started PUT "/admin/countries/1" for 127.0.0.1 at 2017-06-14 16:36:10 +0900
Connecting to database specified by database.yml
Processing by Admin::CountriesController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"/FHMIt6SKjYzWqT7aNROIO6MhC7G6vRYioqCra1D6AI=", "country"=>{"name"=>"spain", "capital"=>"Madrid"}, "commit"=>"Update Country", "id"=>"1"}
  Country Load (0.1ms)  SELECT "countries".* FROM "countries" WHERE "countries"."id" = ? LIMIT 1  [["id", "1"]]
   (0.0ms)  begin transaction
   (0.3ms)  UPDATE "countries" SET "name" = NULL, "updated_at" = '2017-06-14 07:36:11.561304' WHERE "countries"."id" = 1
SQLite3::ConstraintException: NOT NULL constraint failed: countries.name: UPDATE "countries" SET "name" = NULL, "updated_at" = '2017-06-14 07:36:11.561304' WHERE "countries"."id" = 1
   (0.0ms)  rollback transaction
Completed 500 Internal Server Error in 71.7ms

ActiveRecord::StatementInvalid (SQLite3::ConstraintException: NOT NULL constraint failed: countries.name: UPDATE "countries" SET "name" = NULL, "updated_at" = '2017-06-14 07:36:11.561304' WHERE "countries"."id" = 1):
  app/controllers/admin/countries_controller.rb:31:in `update'

  Rendered /Users/sakura/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionpack-3.2.22.5/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.1ms)
  Rendered /Users/sakura/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionpack-3.2.22.5/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (0.9ms)
  Rendered /Users/sakura/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionpack-3.2.22.5/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (24.3ms)
Chino-s commented 7 years ago

@takumiyamamoto

  def update
    @country = Country.find(params[:id])
      if @country.update_attributes(name: params[:name]){ここにkeyを書く}
        redirect_to [:admin, @country], notice: 'Country was successfully updated.'
        logger.debug(puts params[:name])
      else
        render 'edit'
      end
  end

ってことですか?

takumiyamamoto commented 7 years ago

@Chino-s paramsの内容はこんな感じになっている

params = {
  "utf8"=>"✓", 
  "authenticity_token"=>"/FHMIt6SKjYzWqT7aNROIO6MhC7G6vRYioqCra1D6AI=", 
  "country"=>{
     "name"=>"spain", 
     "capital"=>"Madrid"
  }, 
  "commit"=>"Update Country", 
  "id"=>"1"
}

idを取るなら以下だよね??

params[:id]

countryを取るならどうすればいい??

takumiyamamoto commented 7 years ago

@Chino-s

これは全然違う

@country.update_attributes(name: params[:name]){ここにkeyを書く}

以下のイメージだからupdate_attributes(){XXXXXXX}の形にはならない

@country.update_attributes([更新するキー]:  [更新する値])

少し落ち着いて焦らなくていいよ

takumiyamamoto commented 7 years ago
apple_info = {name: 'りんご', price: 120}
orange_info = {name: 'オレンジ', price: 140}

fruits = {apple: apple_info, orange: orange_info}
Chino-s commented 7 years ago

@takumiyamamoto

[更新するキー]: => name:
[更新する値] => params[:name]

ってことじゃないんですか?

takumiyamamoto commented 7 years ago

@Chino-s paramsのすぐ下にはnameっていうキーがない

そもそもparams[:name]なんて入れ物は存在しない

params = {
  "utf8"=>"✓", 
  "authenticity_token"=>"/FHMIt6SKjYzWqT7aNROIO6MhC7G6vRYioqCra1D6AI=", 
  "country"=>{
     "name"=>"spain", 
     "capital"=>"Madrid"
  }, 
  "commit"=>"Update Country", 
  "id"=>"1"
}

これだけでnameなんてない

utf8
authenticity_token
country
commit
id
takumiyamamoto commented 7 years ago

さっきの例も同じ fruits[:name]なんてないから取れない

fruits = {
  apple: {
          name: 'りんご',
           price: 120
   }, 
  orange: {
           name: 'オレンジ', 
           price: 140
   }
}
Chino-s commented 7 years ago

@takumiyamamoto

最初、country_paramsにして コントローラの下にこのように定義したんですけど、 これではないですか?

    def country_params
      params.require(:country).permit(:name, :language, :capital, :area_id, :popular_ranking, :imagephoto, :googlemap)
    end
takumiyamamoto commented 7 years ago

@Chino-s permitに何を渡しているかを理解してる??

takumiyamamoto commented 7 years ago

@Chino-s 一回作業ストップして、このfruitsハッシュからりんごの名前をとってみて

fruits = {
  apple: {
          name: 'りんご',
           price: 120
   }, 
  orange: {
           name: 'オレンジ', 
           price: 140
   }
}
Chino-s commented 7 years ago

@takumiyamamoto

:name, :language, :capital, :area_id, :popular_ranking, :imagephoto, :googlemap これらのカラムじゃないんですか?

takumiyamamoto commented 7 years ago

@Chino-s そこまではあってる

じゃあrequire(:country)は何してる?

Chino-s commented 7 years ago

@takumiyamamoto

countryに尋ねているってことですから countryから引っ張ってくるってことじゃないんですか?

takumiyamamoto commented 7 years ago

@Chino-s あってる!!!

じゃあどう取る???

params = {
  "country"=>{
     "name"=>"spain", 
     "capital"=>"Madrid"
  }, 
}
Chino-s commented 7 years ago

@takumiyamamoto

それがわからないです。

takumiyamamoto commented 7 years ago

@Chino-s もう正解出していい。。。?

Chino-s commented 7 years ago

@takumiyamamoto

はい!

takumiyamamoto commented 7 years ago
params["country"]["name"] 
Chino-s commented 7 years ago

@takumiyamamoto

できました。 連続で繋げて順番立てるんですね!

Chino-s commented 7 years ago

@takumiyamamoto

["name"] この部分を複数選択する場合は、 二行にしなきゃいけないんですか?

takumiyamamoto commented 7 years ago

2行にしないとダメ

params["country"]["name"] 
params["country"]["capital"] 
Chino-s commented 7 years ago

@takumiyamamoto

そしたらif文を二つ作らないといけないんですか?

takumiyamamoto commented 7 years ago

@Chino-s 何がやりたいのかわからないからなぜifが出てきたのかわからん

Chino-s commented 7 years ago

@takumiyamamoto

  def update
    @country = Country.find(params[:id])
      if @country.update_attributes(name: params["country"]["name"])
        redirect_to [:admin, @country], notice: 'Country was successfully updated.'
        logger.debug(puts params[:name])
      else
        render 'edit'
      end
  end

ここにparams["country"]["capital"] を入れるんですよね?

if @country.update_attributes(name: params["country"]["name"])(capital: params["country"]["capital"] ) や if @country.update_attributes(name: params["country"]["name"]) (capital: params["country"]["capital"] ) ってことじゃないですよね?

takumiyamamoto commented 7 years ago

@Chino-s

そもそも一つのメソッドに値を二つ渡す時に なんて渡す方法見てないでしょ・・・。

method(xxxxx)(xxxxx)

こうやる

@country.update_attributes([更新するキー]:  [更新する値], [更新するキー]:  [更新する値])
takumiyamamoto commented 7 years ago

@Chino-s 早めに基礎やったほうが茅野の自信につながりそうだね!!

Chino-s commented 7 years ago

@takumiyamamoto

無事にできました。 さっき同じようなのを作ったんですが、 スペルミスでエラーが出てしまってました。

Chino-s commented 7 years ago

@takumiyamamoto

  def update
    @country = Country.find(params[:id])
      if @country.update_attributes(name: params["country"]["name"],capital: params["country"]["capital"])
        redirect_to [:admin, @country], notice: 'Country was successfully updated.'
        logger.debug(puts params[:name])
      else
        render 'edit'
      end
  end

に対して

  describe  'PUT #update' do

    before :each do
      @country1 = FactoryGirl.create(:country)
      @country2 = FactoryGirl.create(:country, name: "aaaaa")
      @country3 = FactoryGirl.create(:country, name: "")
    end

    context 'correct data' do
    let(:params) { { id: @country1, name: @country2.name } }

      it 'update country data' do
        put :update, params
        @country1.reload
        expect(@country1.name).to eq @country2.name
      end

    end

  end

というテストを書いたんですが、

  1) Admin::CountriesController PUT #update correct data update country data
     Failure/Error: if @country.update_attributes(name: params["country"]["name"],capital: params["country"]["capital"])

     NoMethodError:
       undefined method `[]' for nil:NilClass
     # ./app/controllers/admin/countries_controller.rb:30:in `update'
     # ./spec/controllers/admin/countries_controller_spec.rb:124:in `block (4 levels) in <top (required)>'

NoMethodErrorとなってしまうんですが、、、、

takumiyamamoto commented 7 years ago

30行目ってどこ??

Chino-s commented 7 years ago

@takumiyamamoto

 if @country.update_attributes(name: params["country"]["name"],capital: params["country"]["capital"])

ここです

takumiyamamoto commented 7 years ago

ここを直してみて

let(:params) { { id: @country1, name: @country2.name } }
let(:params) { { id: @country1.id, name: @country2.name } }
Chino-s commented 7 years ago

@takumiyamamoto

  1) Admin::CountriesController PUT #update correct data update country data
     Failure/Error: if @country.update_attributes(name: params["country"]["name"],capital: params["country"]["capital"])

     NoMethodError:
       undefined method `[]' for nil:NilClass
     # ./app/controllers/admin/countries_controller.rb:30:in `update'
     # ./spec/controllers/admin/countries_controller_spec.rb:124:in `block (4 levels) in <top (required)>'

同じでした。

Chino-s commented 7 years ago

@takumiyamamoto

でも、rails server で動かした際は、 ちゃんとできていました。

takumiyamamoto commented 7 years ago

これは変わる?

params["country"]["name"]

params[:country][:name]