Ruby on Rails下拉值不保存

时间:2011-08-14 15:03:35

标签: ruby-on-rails ruby drop-down-menu new-operator save

我是RoR的新手,在尝试从多个下拉列表中保存时遇到问题。我有三个对象 - 书籍,流派和作者。书籍对象具有与其相关联的类型和作者,但问题是我只能设法将类型或作者保存到我的书籍对象,而不是两者。这就是我所在的地方:

class Author < ActiveRecord::Base
validates :name,  :presence => true
validates :biography,  :presence => true
has_many :books
end

class Genre < ActiveRecord::Base
validates :description,  :presence => true
has_many :books
end

class Book < ActiveRecord::Base
 belongs_to :genre
 belongs_to :author
 has_many :cartitems

validates :name,  :presence => true
validates :price,  :presence => true
validates :description,  :presence => true

end

控制器:

def create
#@book = Book.new(params[:book])
@author = Author.find(params[:author].values[0])
@genre = Genre.find(params[:genre].values[0])
@book = @author.books.create(params[:book])
#one or the other saves, but not both
#@book = @genre.books.create(params[:book])
respond_to do |format|
  if @book.save
    format.html { redirect_to(@book, :notice => 'Book was successfully created.') }
    format.xml  { render :xml => @book, :status => :created, :location => @book }
  else
    format.html { render :action => "new" }
    format.xml  { render :xml => @book.errors, :status => :unprocessable_entity }
  end
end

不确定这是否会有所帮助,但以下是视图中的下拉列表:

<div class="field">
<%= f.label :genre %><br />
<%= @items = Genre.find(:all)
select("genre", "description",  @items.map {|u| [u.description,u.id]}, {:include_blank => true})%>

感谢您的任何帮助。

编辑 - 这是我的完整表格。

    <%= form_for(@book) do |f| %>
  <% if @book.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@book.errors.count, "error") %> prohibited this book from being saved:</h2>

      <ul>
      <% @book.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :price %><br />
    <%= f.text_field :price %>
  </div>
  <div class="field">
    <%= f.label :description %><br />
    <%= f.text_area :description %>
  </div>
  <div class="field">
    <%= f.label :genre %><br />
    <%= @items = Genre.find(:all)
    select("genre", "description",  @items.map {|u| [u.description,u.id]}, {:include_blank => true})%>
  </div>
  <div class="field">
    <%= f.label :author %><br />
    <%=@items = Author.find(:all)
    select("author", "name",  @items.map {|u| [u.name,u.id]}, {:include_blank => true}) %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

2 个答案:

答案 0 :(得分:1)

更新您要选择的字段,如下所示:

<div class="field">
  <%= f.label :genre %><br />
  <%= f.select( :genre_id,  Genre.all.map {|u| [u.description,u.id]}, {:include_blank => true}) %>
</div>
<div class="field">
  <%= f.label :author %><br />
  <%= f.select( :author_id, Author.all.map {|u| [u.name,u.id]}, {:include_blank => true}) %>
</div>

你的控制器动作应该是这样的:

def create
  @book = Book.new(params[:book])
  respond_to do |format|
    if @book.save
      format.html { redirect_to(@book, :notice => 'Book was successfully created.') }
      format.xml  { render :xml => @book, :status => :created, :location => @book }
    else
      format.html { render :action => "new" }
      format.xml  { render :xml => @book.errors, :status => :unprocessable_entity }
    end
end

另外,如果您不需要它们,请删除 format.xml 调用,它们只会使您的控制器操作变得混乱。

答案 1 :(得分:0)

有许多不同的方法可以解决您的问题,这有助于确切了解您的params哈希中的内容以及您的完整表单的外观,但无论如何。这是一种方式:

@book = @author.books.create(:genre => @genre)

这是另一个(基本上是同一件事):

@book = @author.books.create {|book| book.genre = @genre}

你也可以单独实例化这本书:

@author = Author.find(params[:author].values[0])
@genre = Genre.find(params[:genre].values[0])
@book = Book.create(:author => @author, :genre => @genre)

我的猜测是你没有正确构建你的表单,否则你的params hash看起来与这个{:book => {:author => 1, :genre => 5}}类似,你可以这样做:

@book = Book.create(params[:book])

您不会使用params[:author]查找作者,但如果您需要执行此操作,则会执行params[:book][:author]