복붙노트

[RUBY-ON-RAILS] 결합 모델의 체크 박스와 추가 필드와 양식을 통해 has_many 레일

RUBY-ON-RAILS

결합 모델의 체크 박스와 추가 필드와 양식을 통해 has_many 레일

나는 (내가 생각으로) 작업을 꽤 일반적인를 해결하기 위해 노력하고있어.

세 가지 모델이있어 :

class Product < ActiveRecord::Base  
  validates :name, presence: true

  has_many :categorizations
  has_many :categories, :through => :categorizations

  accepts_nested_attributes_for :categorizations
end

class Categorization < ActiveRecord::Base
  belongs_to :product
  belongs_to :category

  validates :description, presence: true # note the additional field here
end

class Category < ActiveRecord::Base
  validates :name, presence: true
end

이 제품 새 / 편집 양식에 올 때 내 문제는 시작합니다.

제품을 만들 때 나는에 속해있는 (체크 박스를 통해) 범주를 확인해야합니다. 나는 그것이 '제품 [category_ids] []'와 같은 이름을 가진 체크 박스를 생성하여 수행 할 수 있습니다 알고 있습니다. 그러나 나는 또한 모델 (분류)에 가입에 저장됩니다 확인 관계의 각각에 대한 설명을 입력해야합니다.

나는 거의 StackOverflow에 검색되지 않은 것 등 복잡한 형태, HABTM 체크 박스에 그 아름다운 Railscasts을 보았다. 하지만 성공하지 않았습니다.

난 내 거의 정확히 같은 문제를 설명하는 하나 개의 게시물을 발견했다. 그리고 마지막 대답은 나를 (외모가 갈 수있는 올바른 방법처럼) 몇 가지 의미가 있습니다. 그러나 실제로 잘 작동하지 않습니다 (유효성 검사가 실패 즉 경우). (; 검증 후 전 / 새 / 편집 형태로) 그들이 어디 유효성 검사가 실패 할 경우 체크 박스 등, 체류 나는 종류가 같은 순서로 항상 표시 할

모든 thougts에 감사드립니다. 그래서 가능한 상세으로 환자와 쓰기 바랍니다 (CakePHP의에서 전환) 레일에 새로운 해요. 올바른 방법으로 날 지점주세요!

감사합니다. :)

해결법

  1. ==============================

    1.나는 것 같은데 그것을 알아 냈어! 여기에 내가 가진 무엇 :

    나는 것 같은데 그것을 알아 냈어! 여기에 내가 가진 무엇 :

    내 모델 :

    class Product < ActiveRecord::Base
      has_many :categorizations, dependent: :destroy
      has_many :categories, through: :categorizations
    
      accepts_nested_attributes_for :categorizations, allow_destroy: true
    
      validates :name, presence: true
    
      def initialized_categorizations # this is the key method
        [].tap do |o|
          Category.all.each do |category|
            if c = categorizations.find { |c| c.category_id == category.id }
              o << c.tap { |c| c.enable ||= true }
            else
              o << Categorization.new(category: category)
            end
          end
        end
      end
    
    end
    
    class Category < ActiveRecord::Base
      has_many :categorizations, dependent: :destroy
      has_many :products, through: :categorizations
    
      validates :name, presence: true
    end
    
    class Categorization < ActiveRecord::Base
      belongs_to :product
      belongs_to :category
    
      validates :description, presence: true
    
      attr_accessor :enable # nice little thingy here
    end
    

    양식 :

    <%= form_for(@product) do |f| %>
      ...
      <div class="field">
        <%= f.label :name %><br />
        <%= f.text_field :name %>
      </div>
    
      <%= f.fields_for :categorizations, @product.initialized_categorizations do |builder| %>
        <% category = builder.object.category %>
        <%= builder.hidden_field :category_id %>
    
        <div class="field">
          <%= builder.label :enable, category.name %>
          <%= builder.check_box :enable %>
        </div>
    
        <div class="field">
          <%= builder.label :description %><br />
          <%= builder.text_field :description %>
        </div>
      <% end %>
    
      <div class="actions">
        <%= f.submit %>
      </div>
    <% end %>
    

    그리고 컨트롤러 :

    class ProductsController < ApplicationController
      # use `before_action` instead of `before_filter` if you are using rails 5+ and above, because `before_filter` has been deprecated/removed in those versions of rails.
      before_filter :process_categorizations_attrs, only: [:create, :update]
    
      def process_categorizations_attrs
        params[:product][:categorizations_attributes].values.each do |cat_attr|
          cat_attr[:_destroy] = true if cat_attr[:enable] != '1'
        end
      end
    
      ...
    
      # all the rest is a standard scaffolded code
    
    end
    

    언뜻에서 그것은 잘 작동합니다. 나는 어떻게 든 중단하지 바랍니다 .. :)

    모두 감사합니다. 토론에 참여에 대한 Sandip Ransing 특별 감사. 나는 그것이 나 같은 사람을 위해 유용하게 사용될 수 있기를 바랍니다.

  2. ==============================

    2.즉, 중간 테이블 범주화에 삽입 accepts_nested_attributes_for를 사용 보기 양식처럼 보일 것이다 -

    즉, 중간 테이블 범주화에 삽입 accepts_nested_attributes_for를 사용 보기 양식처럼 보일 것이다 -

    # make sure to build product categorizations at controller level if not already
    class ProductsController < ApplicationController
      before_filter :build_product, :only => [:new]
      before_filter :load_product, :only => [:edit]
      before_filter :build_or_load_categorization, :only => [:new, :edit]
    
      def create
        @product.attributes = params[:product]
        if @product.save
          flash[:success] = I18n.t('product.create.success')
          redirect_to :action => :index
        else
          render_with_categorization(:new)
        end
      end 
    
      def update
        @product.attributes = params[:product]
        if @product.save
          flash[:success] = I18n.t('product.update.success')
          redirect_to :action => :index
        else
          render_with_categorization(:edit)
        end
      end
    
      private
      def build_product
        @product = Product.new
      end
    
      def load_product
        @product = Product.find_by_id(params[:id])
        @product || invalid_url
      end
    
      def build_or_load_categorization
        Category.where('id not in (?)', @product.categories).each do |c|
          @product.categorizations.new(:category => c)
        end
      end
    
      def render_with_categorization(template)
        build_or_load_categorization
        render :action => template
      end
    end
    

    내부보기

    = form_for @product do |f|
      = f.fields_for :categorizations do |c|
       %label= c.object.category.name
       = c.check_box :category_id, {}, c.object.category_id, nil
       %label Description
       = c.text_field :description
    
  3. ==============================

    3.난 그냥 다음을했다. 그것은 나를 위해 일한 ..

    난 그냥 다음을했다. 그것은 나를 위해 일한 ..

    <%= f.label :category, "Category" %>
    <%= f.select :category_ids, Category.order('name ASC').all.collect {|c| [c.name, c.id]}, {} %>
    
  4. from https://stackoverflow.com/questions/9174513/rails-has-many-through-form-with-checkboxes-and-extra-field-in-the-join-model by cc-by-sa and MIT license