এম্বেড থাকা অ্যারে ব্যবহার করে কেন আমার রেলগুলিতে প্রথম-উপাদান সর্বদা ফাঁকা থাকে?


84

আমি রেলগুলি 3.2.0.rc2 ব্যবহার করছি । আমি একটি পেয়েছি Model, যার মধ্যে আমার একটি স্ট্যাটিক রয়েছে Arrayযা আমি একটি ফর্মের মাধ্যমে উপস্থাপন করছি যাতে ব্যবহারকারীরা একটি উপসেট নির্বাচন করতে পারে Arrayএবং একটি নির্বাচনী কলামে সঞ্চিত ডাটাবেসে তাদের নির্বাচন সংরক্ষণ করতে পারে Model। আমি ডাটাবেস কলামে সিরিয়ালাইজ ব্যবহার করেছি যা সঞ্চয় করে Arrayএবং রেলগুলি ব্যবহারকারীদের নির্বাচনকে ইয়ামলে সঠিকভাবে রূপান্তরিত করে (এবং সেই কলামটি পড়ার সময় একটি অ্যারেতে ফিরে আসে)। নির্বাচনগুলি করার জন্য আমি একটি বহু-নির্বাচিত ফর্ম ইনপুট ব্যবহার করছি।

আমার সমস্যাটি হ'ল, বর্তমানে যেভাবে আমার এটি রয়েছে, সার্ভারে প্রেরণ করা হলে ব্যবহারকারীর সাবসেট অ্যারে সর্বদা একটি ফাঁকা প্রথম উপাদান থাকে তা ছাড়া আমি প্রত্যাশা করি সবকিছুই কাজ করে।

এটি কোনও বড় বিষয় নয়, এবং বাস্তবের পরে এটি কেটে দেওয়ার জন্য আমি কোড লিখতে পারি, তবে আমার মনে হয় যে আমি কেবল একরকম সিন্ট্যাক্টিকাল ত্রুটি করছি কারণ এটি আমার কাছে মনে হয় না যে ডিফল্ট রেলস আচরণটি ইচ্ছাকৃতভাবে করবে me কোনও কারণ ছাড়াই এই ফাঁকা উপাদান যুক্ত করুন। আমি অবশ্যই কিছু মিস করেছি বা কোনও ধরণের সেটিংস অক্ষম করতে ভুলে গিয়েছি। আমি কী অনুপস্থিত তা বুঝতে আমাকে সহায়তা করুন (বা এমন কোনও ভাল ডকুমেন্টেশনে আমাকে ইঙ্গিত করুন যা এটি ইন্টার্টুবগুলিতে খুঁজে পেতে সক্ষম হয়েছি তার চেয়ে আরও গভীরতার সাথে এটি বর্ণনা করে)।

মাইএসকিউএল ডেটাবেস টেবিল 'মডেল':

  • একটি কলামযুক্ত নাম অন্তর্ভুক্ত subset_arrayযা একটি পাঠ্য ক্ষেত্র

ক্লাস মডেলটিতে নিম্নলিখিত সেটিংস অন্তর্ভুক্ত রয়েছে:

  • serialize :subset_array
  • ALL_POSSIBLE_VALUES = [value1, value2, value3, ...]

মডেলগুলি সম্পাদনার জন্য ফর্মটিতে নিম্নলিখিত ইনপুট বিকল্পটি অন্তর্ভুক্ত করা হয়েছে:

  • f.select :subset_array, Model::ALL_POSSIBLE_VALUES, {}, :multiple => true, :selected => @model.subset_array

ক্লায়েন্ট থেকে সার্ভারে পুট দেখতে এরকম কিছু দেখাচ্ছে:

  • কেবল মান 1 এবং মান 3 নির্বাচন করা হয়েছে বলে ধরে নেওয়া হচ্ছে
  • "model" => { "subset_array" => ["", value1, value3] }

ডাটাবেস আপডেটটি দেখে মনে হচ্ছে:

  • UPDATE 'models' SET 'subset_array' = '--- \n- \"\"\n- value1\n- value3\n'

আপনি দেখতে পাচ্ছেন, অ্যারেতে এই অতিরিক্ত, ফাঁকা, উপাদান রয়েছে এবং এটি ডাটাবেসে সেট করা হচ্ছে। আমি কীভাবে এ থেকে মুক্তি পাব? আমি আমার f.selectকল থেকে অনুপস্থিত একটি প্যারামিটার আছে ?

অনেক ধন্যবাদ প্রশংসা :)

সম্পাদনা : এটি f.selectবিবৃতি থেকে উত্পন্ন HTML কোড । দেখে মনে হচ্ছে এমন কোনও লুকানো ইনপুট তৈরি হচ্ছে যা আমার সমস্যার কারণ হতে পারে? ওখানে কেন?

<input name="model[subset_array][]" type="hidden" value>
<select id="model_subset_array" multiple="multiple" name="model[subset_array][]" selected="selected">
    <option value="value1" selected="selected">Value1</option>
    <option value="value2">Value2</option>
    <option value="value3" selected="selected">Value3</option>
    <option...>...</option>
</select>

আপনি কি এইচটিএমএল স্নিপেট f.selectতৈরি করতে পারবেন? এছাড়াও, তৈরি করতে এমনকি এই আচরণটি ঘটে, বা এটি কেবল আপডেটে হয়?
মাইক এ।

আউটপুট এইচটিএমএল মার্কআপের EDIT যুক্ত হয়েছেf.select
রব্মক্লার্টি

@ মাইক-এ তৈরি এবং আপডেট উভয়ের জন্য নিশ্চিত একই আচরণ
রব্মক্লার্টি

আমি ভাবছিলাম যে আমি যে ব্রাউজারটি ব্যবহার করছিলাম সে সমস্যার অংশ হতে পারে: এটি কীভাবে নির্বাচিত ট্যাগ হিসাবে একই নামের সাথে লুকানো ইনপুট ট্যাগটির অর্থ ব্যাখ্যা করে এবং প্রকাশ করে। তাই আমি ক্রোম, সাফারি, ফায়ারফক্স এবং অপেরাতে আমার অ্যাপ্লিকেশনটি চেষ্টা করেছিলাম এবং প্রত্যেকে একই ফলাফল তৈরি করে।
রবক্লেয়ার্টি

4
মনে রাখবেন, যে সমস্ত সমাধান ব্যবহার করা include_hidden: falseহয় তা একটি গোচা দিয়ে আসে। আপনি যখন নির্বাচন বাক্স থেকে সমস্ত মান মুছে ফেলেন, আইডোম্যাটিক model.update(something_params)সেই ক্ষেত্রটি অন্তর্ভুক্ত করবে না। টিএল; ডিআর আপনি ক্ষেত্রটি খালি করতে সক্ষম হবেন না।
দামন আও

উত্তর:


51

গোপন ক্ষেত্রটিই কি সমস্যাটি সৃষ্টি করছে। তবে এটি একটি ভাল কারণের জন্য রয়েছে: যখন সমস্ত মানগুলি নির্বাচিত হয়, আপনি এখনও একটি সাবসেট_আরে প্যারামিটার পান। রেল ডক্স থেকে (আপনাকে এগুলি দেখতে ডানদিকে স্ক্রোল করতে হতে পারে):

  # The HTML specification says when +multiple+ parameter passed to select and all options got deselected
  # web browsers do not send any value to server. Unfortunately this introduces a gotcha:
  # if an +User+ model has many +roles+ and have +role_ids+ accessor, and in the form that edits roles of the user
  # the user deselects all roles from +role_ids+ multiple select box, no +role_ids+ parameter is sent. So,
  # any mass-assignment idiom like
  #
  #   @user.update_attributes(params[:user])
  #
  # wouldn't update roles.
  #
  # To prevent this the helper generates an auxiliary hidden field before
  # every multiple select. The hidden field has the same name as multiple select and blank value.
  #
  # This way, the client either sends only the hidden field (representing
  # the deselected multiple select box), or both fields. Since the HTML specification
  # says key/value pairs have to be sent in the same order they appear in the
  # form, and parameters extraction gets the last occurrence of any repeated
  # key in the query string, that works for ordinary forms.

সম্পাদনা: সর্বশেষ অনুচ্ছেদটি পরামর্শ দেয় যে কোনও জিনিস নির্বাচন করা অবস্থায় আপনি খালিটি দেখতে পাচ্ছেন না, তবে আমার মনে হয় এটি ভুল। যে ব্যক্তি এই কারাগারে এই প্রতিশ্রুতিবদ্ধ হয়েছিল ( https://github.com/rails/rails/commit/faba406fa15251cdc9588364d23c687a14ed6885 দেখুন ) চেকবক্সগুলির জন্য রেলগুলি একই কৌশল ব্যবহার করার চেষ্টা করছে (যেমন এখানে উল্লেখ করা হয়েছে: https://github.com / রেল / রেল / টান / 1552 ), তবে আমি মনে করি না এটি একাধিক নির্বাচন বাক্সের জন্য কাজ করতে পারে কারণ প্রেরিত পরামিতিগুলি এই ক্ষেত্রে একটি অ্যারে গঠন করে এবং তাই কোনও মান অগ্রাহ্য করা হয় না।

সুতরাং আমার অনুভূতিটি হ'ল এটি একটি বাগ।


4
আমি কীভাবে এটি সঠিকভাবে পরিচালনা করতে হবে তা বোঝার চেষ্টা করার সময় আমি সমস্যাটি প্রদর্শনের জন্য একটি উদাহরণ অ্যাপ তৈরি করেছি : পি
রবম্যাক্লেটারি

4
আমি মনে করি যে বাগটি অবশ্যই প্রয়োজনীয়ভাবে কারাগারে নেই, তবে এই নির্দিষ্ট উপাদানটির কার্যকারিতাটির জন্য একটি অস্পষ্ট স্পেসিফিকেশন এবং প্রয়োগের ক্ষেত্রে। খালি (বা নির্বাচিত না হওয়া) ফর্ম উপাদানগুলিকে সফল নিয়ন্ত্রণ হিসাবে না বিবেচনা করা হয় এবং এভাবে ফর্মের সামগ্রীর সাথে জমা দেওয়া না হলে কোনও ব্যবহারকারী-এজেন্ট কীভাবে ফর্ম প্রসেসরে নতুন খালি অবস্থার পরিবর্তনের প্রকাশ করতে হবে ?
রবম্যাক্লেটারি

সুতরাং, এটি যদি কোনও বাগ হয় তবে এটি কি রেল ইস্যু ট্র্যাকারে নথিবদ্ধ হয়?
bmihelac

69

4 কারাগারে:

আপনি :include_hiddenবিকল্পটি পাস করতে সক্ষম হবেন । https://github.com/rails/rails/pull/5414/files

আপাতত দ্রুত সমাধান হিসাবে: আপনি এখনই আপনার মডেলটিতে এটি ব্যবহার করতে পারেন:

before_validation do |model|
  model.subset_array.reject!(&:blank?) if model.subset_array
end

এটি কেবলমাত্র মডেল স্তরের সমস্ত ফাঁকা মান মুছে ফেলবে।


ধন্যবাদ বোগদান আমি মনে করি যে এই সমস্যাটি নিয়ে আমি আমার অ্যাপ্লিকেশনটিতে বিষয়টি প্রয়োগ করার জন্য প্রয়োগ করব। ব্যবহারকারী-এজেন্টদের এইচটিএমএল স্পেস বাস্তবায়ন বা কোনও কিছু নিয়ে ইস্যু নিয়ে কাজ করার চেষ্টা করার চেয়ে এটি করা অনেক সহজ।
রবক্লেয়ার্টি

রেল কোর দলের সদস্যদের কাছে আপনার উদ্বেগ আনুন। এগুলি প্যাচগুলি পর্যালোচনা ও গ্রহণ করার অনুমতি দেয় এবং ফলস্বরূপ সমস্যাগুলির জন্য দায় নিতে।
বোগদান গুসিভ

বোগদান, লুকিয়ে থাকা ক্ষেত্রটি বন্ধ করার কোনও উপায় আছে, যদি একাধিক সত্য হয়? এটি আমার অ্যাপ্লিকেশনটিতে 3.2 এ আপগ্রেড করার সময় বেশ কিছু জিনিস ভাঙবে। রেল ম্যাজিকের অতিরিক্ত খালি মান যুক্ত করার কারণে আমাকে কন্ট্রোলারে জিনিসপত্র পরিষ্কার করতে হবে তা সত্যই আমি পছন্দ করি না।
টেলর

ব্যর্থ 4
বোগদান গুসিভ

4
@ দোনাতো আপনাকে অবশ্যই অন্তর্ভুক্ত_কে মিথ্যা (অন্তর্ভুক্ত_গোপনীয়: মিথ্যা) সেট করতে হবে
ফ্লোরিয়ান উইডটম্যান

14

কারাগারে 4+ সেট: অন্তর্ভুক্ত_টি নির্বাচন_ত্যাগে মিথ্যাতে অন্তর্ভুক্ত

<%= form.grouped_collection_select :employee_id, Company.all, :employees, :name, :id, :name, { include_hidden: false }, { size: 6, multiple: true } %>

এটি এখন পর্যন্ত সহজ উত্তর! ধন্যবাদ!
উইলিয়াম হ্যাম্পশায়ার

11

আর একটি দ্রুত সমাধান হ'ল এই নিয়ামক ফিল্টারটি ব্যবহার করা:

def clean_select_multiple_params hash = params
  hash.each do |k, v|
    case v
    when Array then v.reject!(&:blank?)
    when Hash then clean_select_multiple_params(v)
    end
  end
end

এই পদ্ধতিটি মডেল স্তরটিকে স্পর্শ না করেই নিয়ন্ত্রকদের জুড়ে পুনরায় ব্যবহার করা যেতে পারে।


ধন্যবাদ আমি মডেলটিতে এটি না করতে চাইলে আমি এই কৌশলগুলিকে আমার ব্যাগের সাথে যুক্ত করছি;)
রবক্লেয়ার্টি

5

http://api.rubyonrails.org/class/ActionView/Helpers/FormHelper.html#method-i-check_box

গোটচা

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

@ চালান.আপডেট (প্যারামগুলি [: চালান]) পতাকাটি আপডেট করবে না।

এটি প্রতিরোধ করতে সহায়ক চেক বাক্সের আগে একটি সহায়ক গোপন ক্ষেত্র তৈরি করে। লুকানো ক্ষেত্রটির একই নাম এবং এর বৈশিষ্ট্যগুলি একটি চেক না করা চেক বাক্সের নকল করে।

এইভাবে, ক্লায়েন্ট হয় কেবলমাত্র লুকানো ক্ষেত্র (চেক বাক্সটি চেক বাক্সটিকে চেক করা না করে) বা উভয় ক্ষেত্র প্রেরণ করে। যেহেতু এইচটিএমএল স্পেসিফিকেশন বলছে যে কী / মান জোড়াগুলি ফর্মটিতে প্রদর্শিত হবে একই ক্রমে প্রেরণ করতে হবে এবং পরামিতি নিষ্কাশনটি কোয়েরি স্ট্রিংয়ের যে কোনও পুনরাবৃত্ত কীটির সর্বশেষ উপস্থিতি পেয়েছে যা সাধারণ ফর্মগুলির জন্য কাজ করে।

ফাঁকা মান মুছে ফেলতে:

  def myfield=(value)
    value.reject!(&:blank?)
    write_attribute(:myfield, value)
  end


0

params[:review][:staff_ids].delete("")আপডেটের আগে আমি নিয়ামকটি ব্যবহার করে এটি ঠিক করেছি ।

আমার দৃষ্টিতে:

= form_for @review do |f|
  = f.collection_select :staff_ids, @business.staff, :id, :full_name, {}, {multiple:true}
= f.submit 'Submit Review'

আমার নিয়ামক:

class ReviewsController < ApplicationController
  def create
  ....
    params[:review][:staff_ids].delete("")
    @review.update_attribute(:staff_ids, params[:review][:staff_ids].join(","))
  ....
  end
end

0

আমি পৃষ্ঠাটির জাভাস্ক্রিপ্ট অংশে এটি লিখে কাজ করে চলেছি:

$("#model_subset_array").val( <%= @model.subset_array %> );

খনি আরও নীচের মত দেখাচ্ছে:

$("#modela_modelb_ids").val( <%= @modela.modelb_ids %> );

ভবিষ্যতে এটি আমার মাথাব্যথা পেতে যাচ্ছে কিনা তা নিশ্চিত নন তবে এখন এটি ঠিকঠাক কাজ করে।


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