Ошибка «NoMethodError» при сохранении формы вложенных ресурсов в Rails 3 с использованием DataMapper - PullRequest
1 голос
/ 17 июня 2011

В моем контроллере у меня есть:

def index
 @owner = current_user
 @accounts = @owner.accounts.all( :name.not => nil )
 @aliases = @owner.aliases.all( :id.not => nil )
 @transfer = @accounts.transfers.new()
end

def create 
@owner = current_user
 @account = @owner.accounts.first(:id => params[:account_id])
 @alias_out = @owner.aliases.first( :id => params[:alias_from]) 
 @alias_in = Alias.first( :id => params[:alias_to]) 

   @transfer =  @account.transfers.create(params[:transfer])  
                @alias_in.update(:transfers_in => params[:transfer]) 
                @alias_out.update(:transfers_out => params[:transfer]) 

на мой взгляд:

<div id="accounts_list">
   <h2>Your accounts</h2>
    <% @accounts.each do |acc| %>
    <div class="each_element">
      <h3><u><%= acc.name%></u></h3>
      <b>Available money: <u><%= acc.value%> <%=acc.currency%></u></b>
      <div id="create_account">
         <h2>Create an transfer</h2>
    <%= form_for([acc, @transfer]) do |trans_form|%>
         <%= trans_form.label :amount %>
        <%= trans_form.text_field :amount %></br>
        <%= trans_form.fields_for :alias_from do |alias_from|%>
        <%= alias_from.label :alias_from %>
        <%= alias_from.collection_select :id, @aliases, :id, :id %> </br>
        <%end%>
        <%= trans_form.fields_for :alias_to do |alias_to|%>
        <%= alias_to.label :alias_to %>
        <%= alias_to.text_field :id %></br>
        <%end%>
        <%= trans_form.text_area :comment, :rows=>5 %></br>
        <%= trans_form.submit :value => "Transfer" %>
         <%end%>
        </div>
    </div>

    <% end %>
</div>
</div>

и в моих моделях

class Transfer
  include DataMapper::Resource


  belongs_to :account
  belongs_to :alias_from, "Alias", :key =>true
  belongs_to :alias_to, "Alias", :key =>true 



   property :id, Serial
      property :amount, Integer, :required => true
      property :comment, Text


    end

    class Alias
  include DataMapper::Resource


  belongs_to :user
  has n, :transfers_in, "Transfer"  
  has n, :transfers_out, "Transfer"   

  property :id, String, :key => true, :unique => true

  validates_format_of :id, :with => /[0-9a-z\-]/i

end

Все эти результаты для меня с

Started POST "/accounts/2/transfers" for 127.0.0.1

в 2011-06-20 09:16:25 +0400 Обработка TransfersController # create как HTML Параметры: {"utf8" => "✓", "authenticity_token" => "токен "," перевод "=> {" amount "=>" 30.3 "," alias_from "=> {" id "=>" Мой псевдоним "}," alias_to "=> {" id "=>" Его псевдоним "}, "comment" => "текст комментария"}, "commit" => "Transfer", "account_id" => "2"} ~ SQL (0.525ms) SELECT "id", "encrypted_password", "запомнить_created_at","reset_password_token", "reset_password_sent_at", "failed_attempts", "unlock_token", "locked_at", "sign_in_count", "current_sign_in_at", "last_sign_in_at", "current_sign_in_ip", "current_sign_in_ip", "current_sign_in" "user_name", "name_sign_in_ip", "name_sign_in" "name", last_sign_in "" name"," страна "ОТ" пользователей "ГДЕ" id "IN (2) LIMIT 1 ~ SQL (0,495 мс) ВЫБЕРИТЕ" id "," name "," currency "," value "," user_id "FROM" account "WHERE("user_id" = 2 AND "id" = 2) ORDER BY "id" LIMIT 1 ~ SQL (0.414ms) SELECT "id" FROM "псевдонимы "WHERE" id "= 'Мой псевдоним' ORDER BY" id "LIMIT 1 ~ SQL (0.329ms) SELECT" id "FROM" псевдонимы "WHERE" id "= 'Его псевдоним' ORDER BY" id "LIMIT 1 Завершено в15ms

NoMethodError (undefined method `update' for nil:NilClass):
  app/controllers/transfers_controller.rb:10:in

`create '

И я понятия не имею, в чем может быть проблема.Какие-либо предложения?Был бы очень признателен.

1 Ответ

2 голосов
/ 20 июня 2011

mu слишком короткий, это правильно: метод all возвращает коллекцию, а не один объект.Вместо этого вы должны использовать first:

@account = @owner.accounts.first(:id => :account_id)

или get:

@account = @owner.accounts.get(account_id)

Обновление на основена комментарий:

Вы пытаетесь обновить псевдонимы, но это не обязательно.transfer принадлежит alias_from и alias_to.Это означает, что ваша таблица трансфера должна иметь два столбца: alias_from_id и alias_to_id.Вот где вы храните эти значения.

Вам не нужно использовать fields_for.Таким образом, вместо:

<%= trans_form.fields_for :alias_from do |alias_from|%>
  <%= alias_from.label :alias_from %>
  <%= alias_from.collection_select :id, @aliases, :id, :id %> </br>
<%end%>
<%= trans_form.fields_for :alias_to do |alias_to|%>
  <%= alias_to.label :alias_to %>
  <%= alias_to.text_field :id %></br>
<%end%>

Вы должны просто сделать:

<%= trans_form.label :alias_from %>
<%= trans_form.collection_select :alias_from_id, @aliases, :id, :id %> </br>
<%= trans_form.label :alias_to %>
<%= trans_form.text_field :alias_to_id %></br>

И действие вашего контроллера должно выглядеть так:

def create 
  @owner = current_user
  @account = @owner.accounts.first(:id => params[:account_id])
  @transfer =  @account.transfers.create(params[:transfer])  

  # the rest of your code...
end

Обновление 2

Вы можете установить правильные имена полей внешнего ключа в вашей модели следующим образом:

class Transfer
  include DataMapper::Resource    

  belongs_to :account
  belongs_to :alias_from, "Alias", :key => true, :child_key => 'alias_from_id'
  belongs_to :alias_to, "Alias", :key => true, :child_key => 'alias_to_id'

  # Etc...     
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...