Как вызвать метод и отправить новые параметры в RoR? - PullRequest
1 голос
/ 20 июля 2010

Допустим, у меня есть метод A

  def methodA
    note = Note.find(params[:id])
    note.link = params[:link]
    note.linktype = params[:linktype]
    note.save
    redirect_to(notes_url)
  end

Когда я вызываю этот метод с такой точки зрения, он отлично работает

<%= link_to image_tag(w.link, :border =>0), methodA_path(:linktype => w.linktype, :link => w.link, :id => @note.id) %>

Но, если я вызову метод из другого метода в том же контроллере, как это:

def methodB
   ...
   methodA(:id => params[:id], :link => link, :linktype => "image")
end

Я получаю эту ошибку:

wrong number of arguments (1 for 0)

Параметры, которые получает methodA, остаются теми же параметрами, что и methodB, а не теми, которые я отправляю из methodB. Как мне обойти эту проблему? Спасибо за чтение.

Ответы [ 3 ]

4 голосов
/ 20 июля 2010

Несколько вещей:

  • Соглашение об именах в Ruby и, следовательно, в Ruby on Rails заключается в использовании символов подчеркивания, а не верблюда. Так что это должно быть method_a, а не methodA.
  • Похоже, methodA это действие контроллера. Если вы посмотрите на сигнатуру вашего метода, вы не определяете параметры метода. Это хорошо: действия не предпринимаются.
  • Вызов params в действии methodA не обращается к параметрам метода, но обращается к запросу Rails params hash.
  • По вашему мнению, вы на самом деле не вызываете метод. Скорее, вы ссылаетесь на действие, которое при нажатии инициирует запрос, направляемый на это действие. Фактический метод, который вы вызываете - methodA_path, который генерирует URL. Это ярлык для url_for, который автоматически заполняет некоторые параметры для вас (остальные находятся в хэше, который вы передаете). Этот метод был автоматически сгенерирован для вас из ваших маршрутов. Сделайте rake routes из корня вашего приложения для получения дополнительной информации.
  • Если вы хотите вызвать метод действия из methodB, что, вероятно, неразумно, вам не нужно передавать ему параметры. Поскольку methodB также является действием, вызываемым в своем собственном цикле запросов, хэш params все еще доступен для methodA, и он найдет все эти вещи в порядке. Я бы предложил, однако, извлечь любую общую функциональность в третий вспомогательный метод и вызывать ее из каждого действия; вызов действий от других действий кажется мне запахом кода.

Немного резюме: methodA и methodA_path - это разные методы. Первый не принимает параметров, но обращается к хешу параметров запроса Rails, а второй принимает параметры для передачи в url_for.

Это все довольно просто, поэтому я настоятельно рекомендую вам прочитать Agile Web Development с Rails (3-е издание для Rails 2, 4-е для Rails 3).

2 голосов
/ 20 июля 2010

Вызов method_a_path и method_a не совпадают.

  • method_a не принимает параметры. Он обращается к параметрам из хеша params, установленного для экземпляра контроллера во время вызова действия.

  • method_a_path не вызывает method_a, оно просто генерирует URL для вызова метода. Фактический вызов происходит, когда пользователь нажимает на ссылку, а сервер rails обрабатывает запрос.

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

class PostsController < ApplicationController
  def add_media
    add_media_with_para(params)
  end

  def action2
    add_media_with_para(:id => params[:id], :link => link, :linktype => "image")
  end
private

  def add_media_with_para p = {}
    note = Note.find(p[:id])
    note.link = p[:link]
    note.linktype = p[:linktype]
    note.save
    redirect_to(notes_url)    
  end
end

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

posts_add_media_path(:linktype => w.linktype, :link => w.link, :id => @note.id)
0 голосов
/ 20 июля 2010

Я полагаю, под addMedia вы имеете в виду метод A

Обратите внимание, метод methodA_path отличается от methodA. Первый автоматически генерируется, потому что у вас есть маршрут с именем methodA, и он возвращает URL-адрес, необходимый для доступа к этому маршруту. Таким образом, он возвращает строку. В то время как methodA обычно отображает HTML-шаблон.

Если вы хотите делегировать рендеринг другому действию, вы можете сделать что-то вроде этого: redirect_to :action => :methodA, :id => 1, :otherParam => 2

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