Rails: запутались в синтаксисе для передачи локальных переменных в частичные

99

Понимание «магии» Rails в отношении рендеринга частичных файлов (и передачи им локальных переменных).

Почему это работает:

<%= render "rabbits/form" %>

И эта работа:

<%= render "rabbits/form", :parent => @warren, :flash => flash %>

но это не работает:

<%= render "rabbits/form", :locals => { :parent => @warren, :flash => flash } %>

Но это действительно так:

<%= render :partial =>"rabbits/form", :locals => { :parent => @warren, :flash => flash } %>

Кроме того, как я могу найти эти нюансы, чтобы не беспокоить людей на SO?

Мельтеми
источник
3
В комментарии ниже вы сказали, что api-документы rails не доступны для поиска. Вместо этого вам следует попробовать этот сайт: apidock.com/rails . Там также есть рубин и rspec.
ryeguy

Ответы:

152

Короткий ответ: метод рендеринга смотрит на первый аргумент, который вы передаете. Если вы передадите хэш (который включает :partial => 'foo', :locals => {blah blah blah}), то он передаст все ваши аргументы в виде хеша и соответствующим образом проанализирует их.

Если вы передадите строку в качестве первого аргумента, предполагается, что первый аргумент - это ваше частичное имя, а остальная часть будет передана как ваши местные. Однако в этом последующем вызове он фактически назначает :locals => your_locals_argument, которое в данном случае является целым :locals => {locals hash}, а не только {locals hash}; то есть вы получите :locals => {:locals => {locals hash}}, а не :locals => {locals hash}.

Так что мой совет - просто всегда явно передавать значения одним и тем же способом, и у вас не будет проблем. Чтобы узнать об этом, я перешел непосредственно к самому коду ( actionpack / lib / base.rb , render()метод в Rails 2; Rails 3 отличается). Это хорошее упражнение.

Более того, не беспокойтесь о том, чтобы "беспокоить" людей на SO. Вот почему этот сайт существует. Я даже кое-чему научился.

Дуг Р.
источник
5

если вам нужно указать: locals, вам нужно указать: partial или: template

<%= render :partial => "rabbits/form", :locals => {...} %>

должно сработать

Sethvargo
источник
это связано с тем, как Ruby оценивает хеш, если вам это интересно.
sethvargo
Действительно, это работает .. как я указал в своем вопросе ... но мне интересно, почему? и где это задокументировано? только посмотрев на источник? И, если это единственный способ найти и понять эти мириады нюансов в Rails, тогда мне интересно, как и где найти и интерпретировать это из источника. Я не могу просто щелкнуть «рендеринг», а затем перейти к источнику (во всяком случае, не с помощью TextMate), или могу?
Meltemi
1
ах! так что вам действительно интересно :). Да, единственный способ разобраться в этом - это: а) иметь такое же предчувствие, как вы, и б.) Просмотреть исходный код. Я понятия не имею, как
детализировать
хорошо, я укушу ... как вы ищите такие вещи? ты просто копаешься clone https://github.com/rails/rails.git? или есть способ лучше? Извините , но я относительно новый для RoR и до сих пор не нашел хороший / легкий / последовательный способ посмотреть на Rails документации ... такие , что IS - либо. http://api.rubyonrails.org/не легко для поиска. и источник из git тоже не ... вздох
Мельтеми
Я ни в коем случае не эксперт, но использую студию Aptana. Он построен на той же платформе, что и eclipse (если вы знакомы). Это позволяет вам «щелкать» и отслеживать, как вы сказали. Вы также можете выполнить поиск в коде, и он имеет встроенный терминал и т.д. Внимание - это довольно большой файл
sethvargo
2

Честно говоря, я знаю только об этих вариантах использования, потому что я следил за Rails последние пару лет и читал объявления о добавлении нового способа сделать это. Я сам часто ошибаюсь, но обычно это легко исправить.

Если вы спросите меня, это одна из тех частей Rails API, которая не была досконально продумана. С годами он просто накапливал все больше и больше синтаксического сахара, не отказываясь от старого поведения. Способ рендеринга - диабет.

Что еще хуже, рендер ведет себя по-разному в контроллере и в представлении. Я также просматриваю содержимое первого аргумента, чтобы узнать, является ли он файлом, шаблоном, действием или частичным. Если он начинается с косой черты, значит, это файл или что-то в этом роде.

Я предпочитаю по возможности использовать более короткие обозначения. Потому что короткие обозначения хорошо передают намерение. Читая его, он обычно делает то, что вы думаете. Написание частичных выражений непросто.

iain
источник
1

Вот источник метода рендеринга из http://api.rubyonrails.org/classes/ActionView/Rendering.html#method-i-render :

def render(options = {}, locals = {}, &block)
  case options
  # Here is your last case
  when Hash
    if block_given?
      _render_partial(options.merge(:partial => options.delete(:layout)), &block)
    elsif options.key?(:partial)
      _render_partial(options)
    else
      template = _determine_template(options)
      lookup_context.freeze_formats(template.formats, true)
      _render_template(template, options[:layout], options)
    end
  when :update
    update_page(&block)
  else
    # here the first three cases
    _render_partial(:partial => options, :locals => locals)
  end
end

Надеюсь на эту помощь!

Андреа Салицетти
источник
Это действительно помогает , спасибо! Но это не помогает мне помочь себе ... если вы понимаете, о чем я ...
Мельтеми