রেলের আংশিক টেম্পলেটগুলিতে বিকল্প স্থানীয় পরিবর্তনশীল: আমি কীভাবে (সংজ্ঞায়িত? foo) জগাখিচুড়ি থেকে বেরিয়ে আসব?


224

আমি খারাপ বাচ্চা হয়েছি এবং স্থানীয় ভেরিয়েবলের জন্য ডিফল্ট মান নির্ধারণ করতে আমার আংশিক টেম্পলেটগুলিতে নিম্নলিখিত বাক্য গঠনটি ব্যবহার করেছি যদি কোনও মানটি স্পষ্টভাবে সংজ্ঞায়িত না করা হয়: আংশিক রেন্ডারিংয়ের সময় স্থানীয় হ্যাশ -

<% foo = default_value unless (defined? foo) %>

এটি সাম্প্রতিক অবধি কার্যকর হয়ে গেছে বলে মনে হয়েছিল, যখন (কোনও কারণেই আমি বুঝতে পারি না) নন-পাস করা ভেরিয়েবলগুলি এমন আচরণ করা শুরু করেছিল যেন সেগুলি নিল (সংজ্ঞায়িতের পরিবর্তে) হিসাবে সংজ্ঞায়িত করা হয়েছে।

যেমন এসও-তে বিভিন্ন সহায়ক ব্যক্তিদের দ্বারা চিহ্নিত করা হয়েছে, http://api.rubyonrails.org/classes/ActionView/Base.html ব্যবহার করবেন না বলেছে

defined? foo

এবং পরিবর্তে ব্যবহার করতে

local_assigns.has_key? :foo

আমি আমার উপায়গুলি সংশোধন করার চেষ্টা করছি, তবে এর অর্থ প্রচুর টেমপ্লেট পরিবর্তন করা।

আমি কি সামনের দিকে চার্জ করতে এবং সমস্ত টেম্পলেটগুলিতে এই পরিবর্তন করতে পারি? আমার কী দেখার দরকার আছে? আমি প্রত্যেকে কতটা যত্ন সহকারে পরীক্ষা করার দরকার?

উত্তর:


323

আমি এই কাজ:

<% some_local = default_value if local_assigns[:some_local].nil? %>

1
যদিও আমি hgimenez এর পরামর্শ (উপরে) এর কমপ্যাক্ট বাক্য গঠনটি পছন্দ করি, এই পদ্ধতির খুব স্পষ্ট পুনরায় হওয়ার সুবিধা রয়েছে: কী চলছে। (
লোকালটির

1
শূন্যতা পাস করার জন্য আপনার ব্যবহারের ক্ষেত্রে কী?
jonnii

ওহ, আমার মনে একটি নির্দিষ্ট মামলা নেই। কেবল পুরো প্রভাবগুলি বোঝার চেষ্টা করছি। এটি আমাকে এই উত্তরটি গ্রহণ করতে স্মরণ করিয়ে দিয়েছে :-)
ব্রাহ্মণ

4
নীল ইস্যুটি পেতে, আমি ওপি-র লিঙ্ক থেকে কোডটি অনুলিপি করছি ( api.rubyonrails.org/class/ActionView/Base.html ) <% যদি স্থানীয়_অ্যাসাইনস.হাসকি? : শিরোনাম%> শিরোনাম: <% = শিরোনাম%> <% শেষ%> - has_key শূন্য / মিথ্যা পরিস্থিতি এড়িয়ে চলেছে এবং সম্ভবত উত্তরের মতো এখানে একটি লাইনে ছোট করা যেতে পারে
ফিল

5
দয়া করে পাবলো এর উত্তরটি পরীক্ষা করুন: local_assigns.fetchনিল মান সহ পুরো কীগুলি হ্যান্ডেল করে। কীটি একেবারে সেট না করা থাকলে এটি ডিফল্ট ফিরিয়ে দেয়।
কোয়েটজলকোটল

157

যেহেতু local_assignsএকটি হ্যাশ, তাই আপনি alচ্ছিক সাথে আনতেও ব্যবহার করতে পারেন default_value

local_assigns.fetch :foo, default_value

সেট না করা default_valueথাকলে fooএটি ফিরে আসবে ।

সতর্কতা:

কোনও পদ্ধতি local_assigns.fetch :foo, default_valueকখন রয়েছে default_valueসে সম্পর্কে সতর্কতা অবলম্বন করুন , কারণ এর ফলাফলটি পাস করার জন্য এটি যেভাবেই বলা হবে fetch

যদি আপনার default_valueএকটি পদ্ধতি হয় তবে আপনি এটি একটি ব্লকে মোড়ানো করতে পারেন: local_assigns.fetch(:foo) { default_value }এটির প্রয়োজন নেই যখন তার কলটি রোধ করতে।


1
এটি স্পষ্টভাবে বলার অপেক্ষা রাখে: nilমানগুলি এখানে সংরক্ষিত আছে। হ্যাশ থাকে :fooম্যাপ nil, তারপর fetchএটা ফিরে আসবে nil। এটি হ'ল কমপক্ষে আমার v1.9.3 এ। 1.8 কীভাবে আচরণ করেছিল তা আমার মনে নেই।
কোয়েটজলকোটল

এটা সম্পূর্ণ সঠিক। এটি আমার সমস্যার জন্য মনে local_assigns[:foo] || default_valueরেখেছে, যখন foo একটি মিথ্যা মান দেয়, default_valueপরিবর্তে ব্যবহৃত হবে। এটি স্মৃতিচারণের জন্য সাধারণত সমস্যা হয় @some_value ||= expensive_methodযদি পদ্ধতিটি মিথ্যা মান দেয় তবে এটি সর্বদা কার্যকর করা হবে।
পাবলো ক্যান্তেরো

1
এটি সর্বোত্তম উত্তর কেন তা যে বুঝতে পারে না সে যথেষ্ট পরিমাণে রুবি ব্যবহার করেনি। ব্রাভো পাবলো!
মস্তব্লাস্টা

2
একটি অপ্টিমাইজেশন নিম্নলিখিতটি রয়েছে, যাতে আপনার ভেরিয়েবলের প্রতিটি ব্যবহারের জন্য 'ফ্যাচ গার্ড' ব্যবহার না করে কেবল একবার আপনার টেম্পলেটটির শীর্ষে এটি করতে হবে। foo ||= local_assigns[:foo] = local_assigns.fetch(:foo, default_value)
sethcall

আমি ভাবছিলাম কেন এটি কাজ করে না, আমি ধরে foo = local_assigns.fetch :foo, true
নিয়েছিলাম

84

কেমন

<% foo ||= default_value %>

এই বলে "ব্যবহার fooযদি এটা শূন্য বা সত্য নয়। তা না হলে বরাদ্দ default_valuefoo বিন্যাস থেকে"


2
আমি নিশ্চিত নই যে স্থানীয়দের হ্যাশের মধ্য দিয়ে unless
jonnii

1
এটি কাজ করে, তবে আপনার যদি ডিফল্ট মানগুলি থাকে তবে এটি কোনও চিহ্ন যা আপনার কোনও সহায়ক ব্যবহার করা উচিত?
সাইকো

2
এখানে কোন যাদু নেই। বিষয়টিতে
hgmnz

37
সিনট্যাক্সটি এত কমপ্যাক্ট হওয়ায় আমি এই সংস্করণটি সত্যিই পছন্দ করি। আমি মনে করি বড় ক্ষতি এটির অর্থ এই যে আপনি স্থানীয় হিসাবে মান হিসাবে শূন্য বা মিথ্যা পাস করতে পারবেন না, যদিও এটি ডিফল্ট দ্বারা ওভাররাইট করা হবে।
brahn

16
@ ব্রাহন, এটি একটি ভাল বিষয়। আসলে, যদি fooএটি বুলিয়ান হয় তবে এড়ানো উচিত । এটির যথাযথ মূল্য থাকতে পারে falseএবং এটি default_valueদুর্ঘটনাক্রমে ওভাররাইড হয়ে যায় ।
hgmnz

10

আমি মনে করি এটি এখানে পুনরাবৃত্তি করা উচিত ( http://api.rubyonrails.org/classes/ActionView/Base.html থেকে ):

কোনও নির্দিষ্ট রেন্ডার কলটিতে কোনও নির্দিষ্ট স্থানীয় ভেরিয়েবলকে একটি মান নির্ধারণ করা হয়েছে কিনা তা যদি আপনার খুঁজে বের করতে হয় তবে আপনাকে নিম্নলিখিত প্যাটার্নটি ব্যবহার করতে হবে:

<% if local_assigns.has_key? :headline %>
  Headline: <%= headline %>
<% end %>

সংজ্ঞায়িত ব্যবহার করে পরীক্ষা? শিরোনাম কাজ করবে না। এটি একটি বাস্তবায়ন বাধা।


6

আমার ক্ষেত্রে, আমি ব্যবহার করি:

<% variable ||= "" %>

আমার আংশিক
আমি ভাল না তা আমার ধারণা নেই তবে আমার পক্ষে ঠিক আছে


এটি আসলে বেশ ভাল কাজ করে। nilআংশিক কলের পাশাপাশি স্থানীয় হিসাবে পাস করার সময় অপরিজ্ঞাত হয়ে কাজ করে।
জোশুয়া পিন্টার

3
আহ, নীচে পড়ুন, এটি যদি variableবুলিয়ান হয় এবং আপনার এটি সেট করতে হবে তবে এটি ব্যর্থ হবে false। এটি মানটি ব্যবহার না করে ডিফল্ট মান ব্যবহার করবে false। আপনার নিজের ঝুঁকিতে ব্যবহার করুন.
জোশুয়া পিন্টার

5

আমি জানি এটা একটি পুরানো থ্রেড কিন্তু এখানে আমার ছোট অবদান আছে: আমি ব্যবহার করেন local_assigns[:foo].presenceএকটি শর্তাধীন আংশিক ভিতরে। তখন আমি fooকেবলমাত্র রেন্ডার কলটিতে যখন প্রয়োজন তখন সেট করি :

<%= render 'path/to/my_partial', always_present_local_var: "bar", foo: "baz" %>

এ Te একটি চেহারা আছে সরকারী পাগল এখানে গাইড । RoR 3.1.0 থেকে বৈধ Val


আমি local_assigns[:foo]এবং এর মধ্যে কোনও বাস্তব পার্থক্য দেখতে পাচ্ছি না local_assigns[:foo].presence। হ্যাশটিতে nilকীটি উপস্থিত না থাকলে এবং যেটির উপস্থিতি থাকলে মানটি হয় তা কেউই ফিরে আসবে।
জেমসমার্কক

1

আমি মনে করি একটি ভাল বিকল্প যা একাধিক ডিফল্ট ভেরিয়েবলের জন্য অনুমতি দেয়:

<% options = local_assigns.reverse_merge(:include_css => true, :include_js => true) %>
<%= include_stylesheets :national_header_css if options[:include_css] %>
<%= include_javascripts :national_header_js if options[:include_js] %>

1

এটি পাবলো এর উত্তরের ব্যুৎপত্তি। এটি আমাকে একটি ডিফল্ট ('পূর্ণ') সেট করতে দেয় এবং শেষ পর্যন্ত 'মোড' স্থানীয়_অ্যাসাইন এবং একটি আসল স্থানীয় ভেরিয়েবল উভয় ক্ষেত্রে সেট করা হয়।

haml / পাতলা:

- mode ||= local_assigns[:mode] = local_assigns.fetch(:mode, 'full')

ERB:

<% mode ||= local_assigns[:mode] = local_assigns.fetch(:mode, 'full') %>

0

আরও স্বজ্ঞাত এবং কমপ্যাক্ট:

<% some_local = default_value unless local_assigns[:some_local] %>


3
আমি মনে করি যদি আপনার সাথে আংশিক কল এই ব্যর্থ হবে:locals => {:some_local => false}
brahn

0

আপনি যদি প্রতিবার কল করেন তবে স্থানীয় ভেরিয়েবলটিকে আংশিকভাবে পাস করতে না চাইলে আপনি এটি করুন:

<% local_param = defined?(local_param) ? local_param : nil %>

এইভাবে আপনি undefined variableত্রুটি এড়ান। এটি আপনাকে স্থানীয় ভেরিয়েবলগুলির সাথে / ছাড়াই আপনার আংশিক কল করার অনুমতি দেবে।


বা স্থানীয়_প্রেম = স্থানীয়_প্রেম সংজ্ঞায়িত হলে? (স্থানীয়_পরিম)
কিনান খান শেরওয়ানি

0

রুবি ২.৫

ERB

এটি সম্ভব, তবে আপনাকে অবশ্যই আপনার ডিফল্ট মানগুলি সুযোগের মধ্যে ঘোষণা করতে হবে।

পরিবর্তনশীল প্রতিস্থাপন জন্য শব্দ।

# index.html.erb
...
<%= render 'some_content', VARIABLE: false %>
...

# _some_content.html.erb
...
<% VARIABLE = true if local_assigns[:VARIABLE].nil? %>
<% if VARIABLE %>
    <h1>Do you see me?</h1>
<% end %>
...

-6

এর মতো দেখতে কোনও সহায়ক তৈরি করা যেতে পারে:

somearg = opt(:somearg) { :defaultvalue }

প্রয়োগ করা হয়েছে এর মতো:

module OptHelper
  def opt(name, &block)
    was_assigned, value = eval(
      "[ local_assigns.has_key?(:#{name}), local_assigns[:#{name}] ]", 
      block.binding)
    if was_assigned
      value
    else
      yield
    end
  end
end

কীভাবে এবং কেন তা বিশদ জানতে আমার ব্লগটি দেখুন ।

নোট করুন যে এই সমাধানটি আপনাকে ওভাররাইড না করে মান হিসাবে শূন্য বা মিথ্যা পাস করার অনুমতি দেয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.