나는 누군가가 저자와 책의 목록을 작성할 수있는 웹 사이트를 만드는 아주 간단한 응용 프로그램을 작성하여 Rails를 배우려고합니다. 나는 이것이 단순하고 건조한 상태가되기를 바랐지만, 예상치 못한 문제가있었습니다.적절한 Association in Rail을 선택하는 방법은 무엇입니까?
내 모델을 처음 보았을 때 연관성을 설정하고 모든 데이터 요소를 필요로했습니다 (author.name, book.title 및 book.author). 적절한 레일 규칙을 사용하기 때문에 author 또는 author_id를 attr_accessible 목록에 추가하고 싶지 않습니다.
응용 프로그램/모델/author.rb :
class Author < ActiveRecord::Base
attr_accessible :name
validates_presence_of :name
has_many :books
end
응용 프로그램/모델/book.rb :
이class Book < ActiveRecord::Base
attr_accessible :title
validates_presence_of :title
belongs_to :author
validates_associated :author
end
내가 생각하는 책의 컨트롤러와 뷰는 비계 매우 재미에서 정확하게이다. 흥미로운 것은 책 컨트롤러입니다. 새로운 메소드를 살펴보면 ID에 작성자 이름의 배열을 가져 와서 뷰로 전달하는 콜렉터를 추가하는 것이 었습니다. (솔직히, 나는 전혀 ID를 통과하지하는 것을 선호 생각합니다.)
응용 프로그램/컨트롤러/books_controller.rb
# GET /books/new
# GET /books/new.json
def new
@book = Book.new
@authors = Author.all.collect {|a| [a.name, a.id]}
respond_to do |format|
format.html # new.html.erb
format.json { render json: @book }
end
end
을 지금 이상보기에, 나는 기본 new.html.haml을 사용 _form.html.haml을 변경했습니다. @authors의 값을 사용하여 선택 필드를 추가했습니다.
응용 프로그램 /보기/책/_form.html.haml
= form_for @book do |f|
- if @book.errors.any?
#error_explanation
%h2= "#{pluralize(@book.errors.count, "error")} prohibited this book from being saved:"
%ul
- @book.errors.full_messages.each do |msg|
%li= msg
.field
= f.label :name
= f.text_field :name
.field
= f.label :author
= f.select(:author, @authors, {:include_blank => ""})
.actions
= f.submit 'Save'
마지막에게, 나의 컨트롤러로 만드는 방법. 기본 매개 변수를 저장하고 선택한 작성자와 작성자 연결을 만들려고합니다.
응용 프로그램/컨트롤러/books_controller.rb
# POST /books
# POST /books.json
def create
@book = Book.new(params[:book])
@book.author = Author.find_by_id(params[:author])
respond_to do |format|
if @book.save
format.html { redirect_to @book, notice: 'Book was successfully created.' }
format.json { render json: @book, status: :created, location: @book }
else
format.html { render action: "new" }
format.json { render json: @book.errors, status: :unprocessable_entity }
end
end
end
나는 다음과 같은 오류 얻을 '저장'을 클릭하면 : 내가 선택한 값에 넣어 때문에이 것을 이해
Can't mass-assign protected attributes: author
을 params [: author] 대신 params [: book]을 사용하십시오. 그래서 두 가지 질문이 있습니다.
1) select 문을 params [: book] 대신 params [: author]로 보내려면 어떻게 수정해야합니까?
2) ID 연결을 완전히 숨기는 더 좋은 방법이 있습니까?
죄송합니다. label_tag : author를 사용할 수 있습니다. – Geoff
컨트롤러가 @book = Book.new (params [: book]) 및'@book.author = Author.find_by_name (params [: author])'로 변경되었습니다. 이것은 읽기가 쉽고 대량 속성 경고를 발생시키지 않으며 오류로 다시 렌더링해야하는 경우 오류가 표시 될 수있는'@ 책 '이 있음을 보장합니다. – Geoff