ruby-on-rails – 使用Rails find_or_create_by和表单对象
我正在创建一个Rails库应用程序,其中一个类型has_many书籍和一本书属于一种类型.我需要使用表单对象,因为我的数据模型最终会有多个多对多关系,因为我想学习如何使用表单对象.我已经将我的表单对象基于Rails Cast#416表单对象.我的表单,表单对象,模型和控制器似乎都可以工作.新书被创建并且它们与流派相关联,但它们都是流派“流派”.我正在使用find_or_create_by.我认为问题在于book_form.rb,其中@genre || = Genre.find_by(name :: name)实际上没有从表单中传入Genre信息.我的相关代码如下:
模型book.rb class Book < ActiveRecord::Base belongs_to :genre before_save :convert_isbn . . . end 型号genre.rb class Genre < ActiveRecord::Base has_many :books,dependent: :destroy validates_associated :books end book_form.rb class BookForm include ActiveModel::Model def self.model_name ActiveModel::Name.new(self,nil,"Book") end . . . validates :name,presence: true delegate :name,to: :genre delegate :title,:year,:pages,:isbn,:summary,:volume_a,:volume_b,to: :book def genre @genre ||= Genre.find_by(name: :name) end def book @book ||= genre.books.build end def submit(params) genre.attributes = params.slice(:name).permit(:name) book.attributes = params.slice(:title,:volume_b).permit(:title,:volume_b) if valid? genre.save! book.save! true else false end end end books_controller.rb class BooksController < ApplicationController before_action :admin_user,only: [:new,:edit,:destroy] def new @book_form = BookForm.new @genres = Genre.all end def create @book_form = BookForm.new @genres = Genre.all if @book_form.submit(params[:book]) flash[:success] = "You've added a new book to the library!" redirect_to @book_form else render 'new' end end 查看new.html.erb <%= form_for @book_form do |f| %> <%=render 'shared/error_messages',object: f.object %> <%= f.label :title %> <%= f.text_field :title,class: 'form-control' %> . . . <%= f.label :genre %><br> <%= collection_select(:genre,:name,Genre.all,:name) %> <br> <br> <%= f.submit "Add book to library",class: "btn btn-primary" %> <% end %> 使用Pry gem,我在创建一本书时从服务器获取: Started POST "/books" for ::1 at 2016-02-22 14:19:20 -0700 Processing by BooksController#create as HTML Parameters: {"utf8"=>"?","authenticity_token"=>"bPusgyl9n+p07eQsEAe9CpSsithtkg33HMifj8KTsidv3GDLuhjibOC7d2mm5boC4w7ZUne64R4n4OMQotDE4g==","book"=>{"title"=>"test","year"=>"2016","pages"=>"222","isbn"=>"9780-xx-xx-xx","summary"=>"fake summary","volume_a"=>"1","volume_b"=>"2"},"genre"=>{"name"=>"Mystery"},"commit"=>"Add book to library"} From: /home/nathaniel/rails_apps/allredlib/app/forms/book_form.rb @ line 38 BookForm#submit: 37: def submit(params) => 38: binding.pry 39: genre.attributes = params.slice(:name).permit(:name) 40: book.attributes = params.slice(:title,:volume_b) 41: if valid? 42: genre.save! 43: book.save! 44: true 45: else 46: false 47: end 48: end 因此,书籍类型在参数中得到了传递,但我在书本表格中以错误的方式访问它.如果我注释掉binding.pry,那么这个表格会创建一个带有流派“名称”的新书,而不是像我希望它那样的流派“神秘”. 当我使用binding.pry键入@genre到rails时,我得到了 [1] pry(#<BookForm>)> @genre => #<Genre:0x007f19554e1220 id: 20,name: "name",book_id: nil,created_at: Thu,25 Feb 2016 20:28:45 UTC +00:00,updated_at: Thu,25 Feb 2016 20:28:45 UTC +00:00> 最新的binding.pry结果 解决方法
如果您要按名称查找类型,则需要在方法的选项哈希中传入name属性.
def genre @genre ||= Genre.find_or_create_by(name: :name) end UPDATE 更改 genre.attributes = params.slice(:name).permit(:name) 至 genre.attributes = { :name => params[:genre][:name] } 同时在genre.save之前和之后抛出binding.pry!如果你输入@genre,看看你得到了什么,因为你的流派方法应该已经创建了你刚刚用genre.attributes发送params的实例变量接受哈希. 我会考虑书籍参数相同,但如果切片工作得很好. 此外,由于您在窗体视图中调用Genre.all,您可能不需要在控制器操作中执行此操作,但如果这样做,请考虑在窗体视图collection_select中使用对象@genres,因为您’在模型上重复两次所有请求. @genres = Genre.all (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |