'Неизвестный ключ (ы)' ArgumentError - PullRequest
1 голос
/ 16 октября 2010

Я работаю над функцией модерирования для моего приложения, которая основана на базовой структуре скаффолдов.Мне нужно отредактировать несколько записей с логическим параметром publised на falsemoderate.html я получаю список всех неопубликованных записей с возможностью изменения их параметров which, what и published.Ошибка появляется, когда я пытаюсь сохранить изменения с помощью действия * 1007. *.

ArgumentError в NamesController # complete

Неизвестный ключ (ключи): 7, 1,4

"7, 1, 4" - это идентификаторы моих неопубликованных записей.

Вот части моего кода:

#names_controller.rb

    def moderate
     @names = Name.find(:all, params[:name_ids], :conditions => {:published => false})
      respond_to do |format|
        format.html { render :action => "moderate" }
         format.xml 
       end
     end

def complete
     @names = Name.find(params[:name_ids])
     @names.each do |name|
       name.update_attributes!(params[:name].reject { |k,v| v.blank? })
     end
     flash[:notice] = "Updated records!"
     redirect_to names_path
   end


#moderate.html.erb
<% form_tag complete_names_path do %>  
  <% @names.each do |name| %>
    <fieldset>
    <% fields_for "name_ids[#{name.id}]", name do |name_fields| %>
    <%= name_fields.text_field :which %>
    <%= name_fields.text_field :what %>
    <%= name_fields.check_box :published %> 
    <% end %>
    </fieldset>   
  <% end %>  
<%= submit_tag "Ok" %>
<% end %>/


#routes.rb
ActionController::Routing::Routes.draw do |map| 
  map.connect 'moderate', :controller => 'names', :action => 'moderate'
  map.resources :names, :collection => { :complete => :put}
  map.root :names
  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'

Я понимаюЧто-то не так с name_ids, но я не понимаю, что мне делать.Заранее спасибо.

ruby ​​1.8.7 (2009-06-12 patchlevel 174)

[universal-darwin10.0] Rails 2.3.5

Журнал Rails для действий moderate и complete:

Обработка NameSController # умеренный (для 127.0.0.1 в 2010-10-16 21:36:42) [GET] [4; 35; 1mName Load (0,6 мс) [0m [0mSELECT * FROM "names" WHERE ("names". "Опубликовал" = 'F') [0m Шаблон рендеринга в макетах / именах Рендеринг имен / умеренных Завершено за 12 мс(Вид: 7, БД: 1) |200 OK [http://localhost/moderate]

Обработка NamesController # complete (для 127.0.0.1 в 2010-10-16 21:36:49) [POST] Параметры: {"commit" => "Ok", "authenticity_token"=>" CtmsjIavksOMSIArrdovkkzuZzHVjkenFFMO5bHIvgg = "," name_ids "=> {" 7 "=> {" опубликовано "=>" 0 "," what "=>" Партия "," which "=>" Крутая "}," 1"=> {" Опубликовал "=>" 1 "," Что "=>" Россия "," Который "=>" Единая "}," 4 "=> {" Опубликовано "=>" 0 "," Что "=> "Организация", "which" => "Молдавская"}}}
[4; 36; 1mName Load (0,4ms) [0m
[0; 1mSELECT * FROM "names" WHERE ("names"). "id" IN (7,1,4)) [0m

NoMethodError (У вас есть нулевой объект, когда вы его не ожидали! Возможно, вы ожидали экземпляр массива. Произошла ошибка при оценкеnil.reject):
app / controllers / names_controller.rb: 47: в complete'<br> app/controllers/names_controller.rb:46:in каждый '
app / controllers / names_controller.rb: 46: в `complete'

оказанные спасения /_trace (110.3ms) Рендеринг rescues / _request_and_response (0.5ms) Рендеринг rescues / layout (internal_server_error)

1 Ответ

2 голосов
/ 16 октября 2010

Скорее всего, вам нужно получить только ключи из хэша name_ids. Попробуйте:

@names = Name.find(params[:name_ids].keys)

Отдельной проблемой является ваша ссылка на params [: name], которая равна нулю. Вы имели в виду (EDIT: используйте to_s для соответствия ключу params, lol):

@names.each do |name|
  name.update_attributes!(params[:name_ids][name.id.to_s].reject { |k,v| v.blank? })
end

РЕДАКТИРОВАТЬ (краткое пояснение):

То, что происходило, состояло в том, что у вас был вложенный хэш в params, params [: name_ids]. Это выглядело как:

"name_ids"=>{"7"=>{"published"=>"0", "what"=>"Партия", "which"=>"Крутая"}, "1"=>{"published"=>"1", "what"=>"Россия", "which"=>"Единая"}, "4"=>{"published"=>"0", "what"=>"Организация", "which"=>"Молдавская"}}

Метод ActiveRecord 'find' может принимать массив идентификаторов, но не хэш значений. То, что вы изначально отправляли на «найти» в этой строке:

@names = Name.find(params[:name_ids])

... было значением для params [: name_ids]:

{"7"=>{"published"=>"0", "what"=>"Партия", "which"=>"Крутая"}, "1"=>{"published"=>"1", 
"what"=>"Россия", "which"=>"Единая"}, "4"=>{"published"=>"0", "what"=>"Организация", 
"which"=>"Молдавская"}

Когда вы хотели:

@names = Name.find(['7','1','4'])

это то, что вызывает params [: name_ids] .keys.

Вторая проблема была в этой строке:

name.update_attributes!(params[:name].reject { |k,v| v.blank? })

В параметрах не было значения ': name', поэтому вызов 'reject' вызвал ошибку 'no method' - для объекта nil нет метода 'reject'. Вы хотели обновить атрибуты для «имени», которое соответствует конкретному имени в цикле. Это означало, что вы хотели получить значения из params [: name_ids] [: id] где: id - это идентификатор «name».

Все восходит к тому, как fields_for создал параметры для начала. Эта строка:

<% fields_for "name_ids[#{name.id}]", name do |name_fields| %>

означало, что params будет содержать хеш с именем name_ids с ключами, соответствующими name.id, которые сами будут содержать хэши атрибутов, которые ActiveRecord может использовать в методе update_attributes.

Есть много известной магии Rails, которую нужно отследить - это поможет?

...