2010-01-26 4 views
0

Rails новичок здесь, пытаясь получить новый контроллер.неопределенный метод ошибка, но я определил его!

Когда я пытаюсь показать существующий экземпляр ann, я получаю неопределенную ошибку метода для вспомогательного метода. Далее следует код. Любая идея, почему getRecipes будет неопределенным ?!

Контроллер:

def show 
     id = params[:id] 
     recipe_ids = ConcreteMenu.getRecipes(id) 

     respond_to do |format| 
      format.html 
     end 
    end 

Модель

require 'json/objects' 

class ConcreteMenu < ActiveRecord::Base 
    has_many :menu_recipes 
    has_many :recipes, :through => :menu_recipes 

    belongs_to :menu 

    def self.getRecipes(id) 
     recipes = MenuRecipe.find(:all, :conditions => {:concrete_menu_id => id}, :select => 'id') 
    end 
end 
+1

Я бы рекомендовал рефакторинг для предпочтительного стиля Ruby 'def self.foo' вместо' def self.getFoo'. – Eli

+0

Другое дело, в ruby ​​methods_are_named_like_this. Вы из Явы? – jonnii

+0

Не могли бы вы разместить трассировку стека? Я бы сказал, что проблема находится вне кода, который вы опубликовали. Кроме того, я согласен с Eli и добавляю, что конвенция Ruby - это snake_case, а не camelCase. – Ben

ответ

2

Это поможет, если вы вставили текст ошибки, потому что ваше объяснение оставляет много возможностей для того, что может быть неправильным. BUT, есть более простой способ получить то, что вы хотите. Значение определения «HAS_MANY» отношений является то, что вместо вызова метода класса и передавая идентификатор конкретного меню, чтобы получить связанные с ней рецепты, вы можете просто сделать это:

def show 
    @concrete_menu = ConcreteMenu.find(params[:id], :include => :recipes) 
end 

Теперь вы будете иметь меню object и @concrete_menu.recipes возвращает массив рецептов, в котором вы нуждаетесь. Эта функция уже встроена, нет необходимости изобретать велосипед.

Кроме того, я заметил, что вы пытались собрать идентификаторы в контроллере вместо самих объектов. Это говорит о том, что вы возвращаетесь и фактически извлекаете записи в самом представлении. Это менее эффективно и сложнее устранить проблему, если все пойдет не так. Мой пример выше будет делать то, что вам нужно, в лучшем (и более приемлемом для рельсов) пути.

1

Как вы его там определено, оно должно быть доступно. Есть ли вероятность, что у вас есть что-то еще, называемое ConcreteMenu, но в другом контексте?

Чтобы быть уверенным, что вы звоните правильный, где может быть двусмысленности, вы можете обратиться к классу верхнего уровня:

recipe_ids = ::ConcreteMenu.getRecipes(id) 

Другой способ проверить, что метод определен правильно с помощью сценарий/консоль:

ConcreteMenu.methods.grep(/getRecipe/) 
# => ["getRecipes"] 

Это предполагая, конечно, у вас возникли проблемы с методом getRecipes. Там есть возможность вы спутать как переменные контроллера передаются к просмотру:

def show 
    @id = params[:id] 
    @recipe_ids = ConcreteMenu.getRecipes(@id) 

    respond_to do |format| 
     format.html 
    end 
end 

Любые переменные экземпляра, определенные (@ ...) не будут доступны в контексте зрения, но больше не будет каких-либо локальных переменных быть определены, поскольку они выходят за рамки.

Смежные вопросы