Open Chino-s opened 7 years ago
こんな書き方はしないよ
@country.update_attributes(:name, :capital)
こうなるはず
@country.update_attributes(name: "変更する内容")
これの違いはわかる??
name:
:name
@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
これがダメ
@country.update_attributes(params[:name])
これは文字列が入っている入れ物でしかない
params[:name]
やってるのはこれと同じことになる
@country.update_attributes("台湾")
どこのからむを変更するっていうキーの情報がない
@takumiyamamoto
仕組みはわかったんですが、 <%= f.text_field :name %>テキストボックスに入力された 文字列をどのように name: に入れるんですか?
参考サイト調べて見たんですが、 どこも({ name: "Isaac Newton", age: 35 })このように代入方法で行なっているため、、、
@Chino-s
以下で取れると思うよ
params[:name]
こんな感じでテストの時だけプログラムに入れておくと パラメータの中にどんなものが入ってるのかをコンソールのログでみれたりするよ
puts params
コントローラーに書くならこんな感じかな
@country.update_attributes(name: params[:name])
@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
@Chino-s
この書き方ダメ(本日2回目)
@country.update_attributes(params[:name])
@takumiyamamoto
params[:name] これで取れるんですよね?
@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
こういうことですか?
@Chino-s それで動かしてみ
not nullのエラーになってしまいました。
コントローラの中にこれを入れて パラメータの中にどんなものが入っているのかをコンソールのログを見て確認する
puts params
@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
こういうことですよね?
@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)
@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
ってことですか?
@Chino-s paramsの内容はこんな感じになっている
params = {
"utf8"=>"✓",
"authenticity_token"=>"/FHMIt6SKjYzWqT7aNROIO6MhC7G6vRYioqCra1D6AI=",
"country"=>{
"name"=>"spain",
"capital"=>"Madrid"
},
"commit"=>"Update Country",
"id"=>"1"
}
idを取るなら以下だよね??
params[:id]
countryを取るならどうすればいい??
@Chino-s
これは全然違う
@country.update_attributes(name: params[:name]){ここにkeyを書く}
以下のイメージだからupdate_attributes(){XXXXXXX}
の形にはならない
@country.update_attributes([更新するキー]: [更新する値])
少し落ち着いて焦らなくていいよ
apple_info = {name: 'りんご', price: 120}
orange_info = {name: 'オレンジ', price: 140}
fruits = {apple: apple_info, orange: orange_info}
@takumiyamamoto
[更新するキー]: => name:
[更新する値] => params[:name]
ってことじゃないんですか?
@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
さっきの例も同じ fruits[:name]なんてないから取れない
fruits = {
apple: {
name: 'りんご',
price: 120
},
orange: {
name: 'オレンジ',
price: 140
}
}
@takumiyamamoto
最初、country_paramsにして コントローラの下にこのように定義したんですけど、 これではないですか?
def country_params
params.require(:country).permit(:name, :language, :capital, :area_id, :popular_ranking, :imagephoto, :googlemap)
end
@Chino-s permit
に何を渡しているかを理解してる??
@Chino-s 一回作業ストップして、このfruitsハッシュからりんごの名前をとってみて
fruits = {
apple: {
name: 'りんご',
price: 120
},
orange: {
name: 'オレンジ',
price: 140
}
}
@takumiyamamoto
:name, :language, :capital, :area_id, :popular_ranking, :imagephoto, :googlemap これらのカラムじゃないんですか?
@Chino-s そこまではあってる
じゃあrequire(:country)
は何してる?
@takumiyamamoto
countryに尋ねているってことですから countryから引っ張ってくるってことじゃないんですか?
@Chino-s あってる!!!
じゃあどう取る???
params = {
"country"=>{
"name"=>"spain",
"capital"=>"Madrid"
},
}
@takumiyamamoto
それがわからないです。
@Chino-s もう正解出していい。。。?
@takumiyamamoto
はい!
params["country"]["name"]
@takumiyamamoto
できました。 連続で繋げて順番立てるんですね!
@takumiyamamoto
["name"] この部分を複数選択する場合は、 二行にしなきゃいけないんですか?
2行にしないとダメ
params["country"]["name"]
params["country"]["capital"]
@takumiyamamoto
そしたらif文を二つ作らないといけないんですか?
@Chino-s 何がやりたいのかわからないからなぜifが出てきたのかわからん
@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"] ) ってことじゃないですよね?
@Chino-s
そもそも一つのメソッドに値を二つ渡す時に なんて渡す方法見てないでしょ・・・。
method(xxxxx)(xxxxx)
こうやる
@country.update_attributes([更新するキー]: [更新する値], [更新するキー]: [更新する値])
@Chino-s 早めに基礎やったほうが茅野の自信につながりそうだね!!
@takumiyamamoto
無事にできました。 さっき同じようなのを作ったんですが、 スペルミスでエラーが出てしまってました。
@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となってしまうんですが、、、、
30行目ってどこ??
@takumiyamamoto
if @country.update_attributes(name: params["country"]["name"],capital: params["country"]["capital"])
ここです
ここを直してみて
let(:params) { { id: @country1, name: @country2.name } }
let(:params) { { id: @country1.id, name: @country2.name } }
@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)>'
同じでした。
@takumiyamamoto
でも、rails server で動かした際は、 ちゃんとできていました。
これは変わる?
params["country"]["name"]
params[:country][:name]
@takumiyamamoto
こういうことでしょうか? これを実行したところ、このようなエラーが出てしまいました。 カラム指定の方法が悪いのでしょうか?