IT박스

Rails 3 : 연관을 통해 has_many를 사용하는 다중 선택

itboxs 2021. 1. 10. 16:59
반응형

Rails 3 : 연관을 통해 has_many를 사용하는 다중 선택


여러 선택으로 하나의 게시물에 대해 여러 카테고리를 선택할 수있는 가능성을 얻고 싶습니다.

다음 모델이 있습니다 : Post, Category 및 PostCategory.

class Post < ActiveRecord::Base
  has_many :post_categories
  has_many :categories, :through => :post_categories
end

class Category < ActiveRecord::Base
  has_many :post_categories
  has_many :posts, :through => :post_categories
end

class PostCategory < ActiveRecord::Base
  has_one    :post
  has_one    :category
  belongs_to :post      # foreign key - post_id
  belongs_to :category  # foreign key - category_id
end

내 컨트롤러에는 @post = Post.new와 같은 것이 있습니다. 몇 가지 카테고리를 만들었습니다.

그리고 나는 다음을 가지고 있습니다.

<%= form_for @post do |f| %>
    <%= f.text_field :title %>
    <%= f.select :categories, :multiple => true %>
    <%= f.submit %>
<% end %>

그리고 ... 내 카테고리는 어디에 있습니까? 선택 옵션에 "여러"만 있습니다. 내 양식에 문제가 있다고 생각합니다.


죽은자를 부활 시켜서 미안하지만 기본 컨트롤러 동작 코드를 사용하고 has_many에 ActiveModel setter 로직을 사용할 수있는 훨씬 더 간단한 솔루션을 찾았습니다. 예, 그것은 완전히 마술입니다.

<%= f.select :category_ids, Category.all.collect {|x| [x.name, x.id]}, {}, :multiple => true %>

특히 : category_ids (또는 : your_collection_ids) 매개 변수 이름을 사용하면 Rails가 자동으로 @ post.category_ids = params [: post] [: category_ids]를 호출하여 해당 게시물에 대한 카테고리를 설정하도록합니다. 모두 기본 컨트롤러 / 스캐 폴드를 수정하지 않고 # 코드 생성 및 # 업데이트.

아, 그리고 has_many : something, through : : something_else와 함께 작동하여 조인 모델을 자동으로 관리합니다. 굉장해.

따라서 OP에서 필드 / 매개 변수 이름을 : categories 대신 : category_ids로 변경하십시오.

그러면 편집 양식에서 강조 표시된대로 모델의 선택한 범주가 선택 필드에 자동으로 채워집니다.

참조 :

이것을 찾은 has_many API 문서 에서.

또한 양식 도우미 가이드의 경고 는 적절한 양식 필드 / 매개 변수 이름을 사용하지 않을 때이 "유형 불일치"를 설명합니다.

적절한 양식 필드 / 매개 변수 이름을 사용하면 Rails 방식에서 권장하는대로 새 양식을 건조하고 양식을 편집하고 컨트롤러를 얇게 유지할 수 있습니다.

레일 4 및 강력한 매개 변수에 대한 참고 사항 :

def post_params
  params.require(:post).permit(:title, :body, category_ids: [])
end

게시물의 카테고리를 구성하는 최종 솔루션이 유용하기를 바랍니다.

여러 개를 사용하려면 select_tag가 필요합니다.

<%= select_tag "categories", options_from_collection_for_select(Categories.all, 'id', 'name'), :multiple => true %>

또는 f.select ( Tigraine 및 Brent 덕분에 많은 감사합니다! ), 더 우아한 방법입니다.

<%= f.select :categories, Category.all.collect {|x| [x.name, x.id]}, {}, :multiple => true %>

컨트롤러의 작업을 생성하려면 다음이 필요합니다.

def create
   @post = Post.new(params[:post])

if @post.save

  params[:categories].each do |categories|
     categories = PostCategory.new(:category_id => categories, :post_id => @post.id)
     if categories.valid?
       categories.save
     else
       @errors += categories.errors
     end
  end
  redirect_to root_url, :notice => "Bingo!"
else
  render "new"
end
end

필요한 것은 선택 옵션 목록입니다.

<%= f.select :category_id, Category.all.collect {|x| [x.name, x.id]}, :multiple => true %>

Tigraine이 거의 가지고 있었지만 추가로 빈 해시를 지정해야합니다.

<%= f.select :category_id, Category.all.collect {|x| [x.name, x.id]}, {}, :multiple => true %>


As the @post does not have id, the from might not display categories as there is no association. You need to pass do a build on @post something like

 @post = Post.new(:categories => Category.all)

ReferenceURL : https://stackoverflow.com/questions/8826407/rails-3-multiple-select-with-has-many-through-associations

반응형