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
ในความคิดเห็นด้านล่างคุณได้บอกว่าเอกสารของ rail api ไม่สามารถค้นหาได้ คุณควรพยายามเว็บไซต์นี้แทน: 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()วิธีการในทางรถไฟ 2; Rails 3 ที่แตกต่างกัน) มันเป็นการออกกำลังกายที่ดี

นอกจากนี้ไม่ต้องกังวลว่าจะ "รบกวน" ผู้คนใน SO นั่นเป็นเหตุผลที่มีไซต์นี้ ฉันได้เรียนรู้บางอย่างจากสิ่งนี้


5

หากคุณต้องการระบุ: local คุณต้องระบุ: partial หรือ: template

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

ควรทำงาน


มันเกี่ยวข้องกับวิธีที่ทับทิมประเมินแฮชหากคุณอยากรู้อยากเห็นด้วยวิธีนั้น
sethvargo

ได้ผลจริง.. ตามที่ระบุไว้ในคำถาม ... แต่ที่สงสัยคือทำไม? และเอกสารนี้อยู่ที่ไหน? โดยดูจากแหล่งที่มาเท่านั้น? และถ้านั่นเป็นวิธีเดียวที่จะพบและทำความเข้าใจเกี่ยวกับมากมายเหล่านี้ของความแตกต่างในทางรถไฟแล้วฉันสงสัยว่าวิธีการและสถานที่ที่จะไปเกี่ยวกับตำแหน่งและการตีความนี้จากแหล่งที่มา ฉันไม่สามารถคลิกที่ "เรนเดอร์" แล้วเจาะลึกลงไปที่ซอร์สได้ (ไม่ใช่ด้วย TextMate) หรือฉันสามารถ?
Meltemi

1
อา! ดังนั้นคุณจึงสนใจจริงๆ :) ใช่วิธีเดียวที่จะเข้าใจสิ่งเหล่านี้คือ a.) มีลางสังหรณ์เหมือนที่คุณทำและ b.) ดูซอร์สโค้ด ฉันไม่รู้ว่าจะเจาะลึกแหล่งที่มาได้อย่างไร ... ขออภัย
sethvargo

ตกลงฉันจะกัด ... คุณมองหาของแบบนี้ได้อย่างไร? คุณแค่เจาะลึกของคุณclone https://github.com/rails/rails.git? หรือมีวิธีที่ดีกว่านี้ไหม ขออภัยฉันค่อนข้างใหม่กับ RoR และยังไม่พบวิธีที่ดี / ง่าย / สม่ำเสมอในการค้นหาเอกสาร Rails ... ซึ่งนั่นก็คือมีเลย http://api.rubyonrails.org/ไม่สามารถค้นหาได้ง่าย และแหล่งที่มาจาก git ก็ไม่ใช่เช่นกัน ... ถอนหายใจ
Meltemi

ฉันไม่ใช่ผู้เชี่ยวชาญ แต่อย่างใด แต่ฉันใช้ Aptana studio สร้างบนแพลตฟอร์มเดียวกับ eclipse (ถ้าคุณคุ้นเคย) ช่วยให้คุณ "คลิก" และติดตามอย่างที่คุณพูด นอกจากนี้คุณยังสามารถค้นหาในรหัสและมีเทอร์มินัลในตัวเป็นต้นข้อควรระวัง - ไฟล์ใหญ่มาก
sethvargo

2

เพื่อเป็นเกียรติแก่ฉันรู้เพียงเกี่ยวกับกรณีการใช้งานเหล่านี้เนื่องจากฉันติดตาม Rails มาตลอดสองสามปีที่ผ่านมาและอ่านประกาศว่ามีการเพิ่มวิธีการใหม่ในการทำเช่นนี้ ฉันมักจะทำผิดพลาดด้วยตัวเอง แต่โดยปกติแล้วจะแก้ไขได้ง่าย

เป็นส่วนหนึ่งของ Rails API ที่ยังไม่ได้รับการพิจารณาอย่างละเอียดหากคุณถามฉัน มันสะสมน้ำตาลที่มีปฏิกิริยามากขึ้นเรื่อย ๆ ในช่วงหลายปีที่ผ่านมาโดยไม่เลิกใช้พฤติกรรมเก่า ๆ วิธีเรนเดอร์มีเบาหวาน

เพื่อให้แย่ยิ่งขึ้นการแสดงผลจะทำงานแตกต่างกันในตัวควบคุมและมุมมอง ฉันยังดูเนื้อหาของอาร์กิวเมนต์แรกเพื่อดูว่าเป็นไฟล์เทมเพลตการกระทำหรือบางส่วน ถ้ามันขึ้นต้นด้วยเครื่องหมายทับแสดงว่าเป็นไฟล์หรืออะไรทำนองนั้น

ฉันชอบใช้สัญกรณ์ที่สั้นกว่าทุกครั้งที่ทำได้ เนื่องจากสัญกรณ์สั้น ๆ สื่อถึงเจตนาได้ดีทีเดียว เมื่ออ่านมันมักจะทำในสิ่งที่คุณคิด การเขียนบางส่วนไม่ตรงไปตรงมา


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

หวังว่านี่จะช่วยได้!


สิ่งนี้ช่วยได้ขอบคุณ! แต่มันไม่ช่วยให้ฉันช่วยตัวเอง ... ถ้าคุณรู้ว่าฉันหมายถึงอะไร ...
Meltemi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.