ruby on rails रेलवे 4 अन्य टेक्स्ट_फ़ील्ड के साथ चेकबॉक्सों के संग्रह के साथ फ़ॉर्म को मॉडल कैसे करें




ruby-on-rails checkbox (3)

दूसरे को अपने मॉडल में न रखें, न ही इसका नाम है! यदि आप अपनी posts लिए form_for का उपयोग कर रहे हैं, तो बस कोई असंबद्ध फ़ील्ड जोड़ें।

उदा: f.text_field :other_name to text_field_tag :other_name

मैन्युअल रूप से ड्रॉपडाउन संग्रह में अपना Other विकल्प जोड़ें।

यदि अन्य चुना हुआ है, तो आप छुपा पाठ फ़ील्ड छुपाने और प्रदर्शित करने के लिए जेएस जोड़ सकते हैं।

आपके पोस्ट_कंट्रोलर में करें:

def create
  ...
  if params[:other_name]
    post.categories.create(name: param[:other_name])
  end
  ...
end

मुझे पहले यह कहकर शुरू करें कि यह एक मॉडलिंग समस्या भी हो सकती है और मैं मॉडल सुझावों के लिए खुला हूँ

केस का उपयोग करें: मेरे पास एक फ़ॉर्म है और मुझे किसी उपयोगकर्ता को अपने पोस्ट की श्रेणी पर एक चेकबॉक्स चुनने की अनुमति है। यदि कोई ऐसा श्रेणी नहीं है जो उनकी पोस्ट को फिट बैठता है तो अन्य श्रेणी की जांच करने के लिए उपयोगकर्ता को एक कस्टम श्रेणी जोड़ने के लिए टेक्स्ट फ़ील्ड दिखाई देगी। यह नेस्टेड मॉड्यूल बनाने और अपडेट करने के लिए होना चाहिए

डीबी मॉडलिंग

class CreateCategories < ActiveRecord::Migration
  def change
    create_table :categories do |t|
      t.string :name, null: false
      t.timestamps null: false
    end

    reversible do |dir|
      dir.up {
        Category.create(name: 'Hats')
        Category.create(name: 'Shirts')
        Category.create(name: 'Pants')
        Category.create(name: 'Shoes')
        Category.create(name: 'Other')
      }
    end

    create_table :categorizations, id: false do |t|
      t.belongs_to :post, index: true, null: false
      t.belongs_to :category, index: true, null: false
      t.string :value
    end
  end
end

ऐप मॉडल

class Post < ActiveRecord::Base
  has_many :categorizations
  accepts_nested_attributes_for :categorizations, allow_destroy: true
  has_many :categories, through: :categorizations
  accepts_nested_attributes_for :categories
end

class Category < ActiveRecord::Base
  has_many :posts
end

नियंत्रक:

  def update

    if @post.update(post_params)
      flash.now[:success] = 'success'
    else
      flash.now[:alert] = @post.errors.full_messages.to_sentence
    end

    render :edit
  end

  private

  def set_post
    @post = Post.find(params[:id])
    (Category.all - @post.categories).each do |category|
      @post.categorizations.build(category: category)
    end
    @post.categorizations.to_a.sort_by! {|x| x.category.id }
  end

  def post_params
    params.require(:post).permit(:name, :description,
                                categorizations_attributes: [ :category_id, :value, :_destroy],
                                )
  end

राय:

= f.fields_for :categorizations do |ff|
    = ff.check_box :_destroy, { checked: ff.object.persisted? }, '0', '1'
    = ff.label :_destroy, ff.object.category.name
    = ff.hidden_field :category_id
    = ff.text_field :value if ff.object.category.other?

हालांकि उपरोक्त समाधान के साथ मैं बचत करते समय रिकॉर्ड त्रुटियों को डुप्लिकेट करने के लिए जारी रखता हूं। यकीन नहीं क्यों हो रहा है? क्या ऐसा करने के लिए इससे अच्छा तरीका है?


मुझे ऐसा कुछ पसंद है:

मॉडल के

post.rb

class Post < ActiveRecord::Base
  has_many :categorizations
  has_many :categories, through: :categorizations

  accepts_nested_attributes_for :categorizations, allow_destroy: true
  accepts_nested_attributes_for :categories
end

category.rb

class Category < ActiveRecord::Base
  has_many :categorizations
  has_many :posts, through: :categorizations
end

नियंत्रक

...
def update
  if @post.update(post_params)
    flash.now[:success] = 'success'
  else
    flash.now[:alert] = @post.errors.full_messages.to_sentence
  end
  render :edit
end

private

def set_post
  @post = Post.find(params[:id])
end

def post_params
  params.require(:post).permit(:name, :description, category_ids: [])
end
...

दृश्यों को मैं सामान्य रूप से सादे। .erb , इसलिए .erb सहायता से

<%= simple_form_for(@post) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :content -%>
    ...
  </div>

  <div class="form-inputs">
    <%= f.association :categories, as: :check_boxes -%>
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

आप जाँच / अनियंत्रित राज्यों को देख सकते हैं और इस तरह से आसानी से और साफ तरीके से नष्ट कर सकते हैं। इसके अलावा, आप जोड़ सकते हैं

<%= f.simple_fields_for :category do |category_fields| %>
  <%= category_fields.input :name -%>
<% end %>

संघों के लिए नेस्टेड फ़ील्ड प्राप्त करने के लिए, लेकिन जब आप ऐसा करते हैं तो strong_params से संबंधित पैरामीटर जोड़ने के लिए मत भूलना।

...
def post_params
  params.require(:post).permit(:name, :description, category_attributes: [:name])
end
....

उपयोगकर्ता को "अन्य" श्रेणी का चयन करने और उसके बाद टेक्स्ट फ़ील्ड कहीं और संग्रहीत करने के बजाय, आपको इसके बजाय एक नया श्रेणी उदाहरण बनाना चाहिए। आप accepts_nested_attributes_for साथ सही रास्ते पर हैं

अगला कदम होगा:

# app/controllers/posts_controller.rb

def new
  @post = Post.new
  @post.build_category
end

private
  # don't forget strong parameters!
  def post_params
    params.require(:post).permit(
      ...
      category_attributes: [:name]
      ...
    )
  end

दृश्य ( simple_form और nested_form रत्नों का उपयोग करके)

# app/views/new.html.haml
= f.simple_nested_form_for @job do |f|
  = f.simple_fields_for :category do |g|
    = g.input :name

आप इसके बजाय फॉर्म ऑब्जेक्ट का उपयोग करके यह क्लीनर भी कर सकते हैं।

संपादित करें: यदि आपको मूल श्रेणियों से अन्य श्रेणियों की चिंताओं को अलग करने की आवश्यकता है, तो आप ऐसा करने के लिए ओ ओ वारंट का उपयोग कर सकते हैं। यह करने का रेलवे मार्ग एकल तालिका विरासत है

# app/models/category.rb
class Category < ActiveRecord::Base
end

# app/models/other_category.rb
class OtherCategory < Category
end

# app/models/original_category.rb
class OriginalCategory < Category
end




models