Rails 4 - 许多类别不会保存到数据库

时间:2014-02-07 10:58:17

标签: ruby-on-rails ruby ruby-on-rails-4

我有3个表,分别是引脚(帖子),流派(类别)和genre_pin(引脚和流派之间有很多对,因为引脚可以有很多类型)。

我正在尝试构建创建表单,这将允许用户在引脚上选择任意数量的类型并保存/创建。创建工作正常没有错误,但它没有保存任何关系记录到genre_pin表。我很确定我可能会遗漏一些非常明显的东西。

我使用的是“引脚”和“流派”这两个词,但您可以将其视为“帖子”和“类别”。

Pin Model

class Pin < ActiveRecord::Base

    belongs_to :user
    belongs_to :type
    has_many :replies
    has_many :genre_pins
    has_many :genres, :through => :genre_pins

    accepts_nested_attributes_for :genres, allow_destroy: true, reject_if: proc { |genre| genre[:id].blank? }

    validates :user_id, presence: true
    validates :type_id, presence: true
    validates :title, presence: true
    validates :description, presence: true

end

流派模式

class Genre < ActiveRecord::Base

    has_many :genre_pins
    has_many :pins, :through => :genre_pins

    validates :title, presence: true

end

GenrePin模型

class GenrePin < ActiveRecord::Base

    belongs_to :pin
    belongs_to :genre

    validates_uniqueness_of :pin_id, :scope => :genre_id

end

接下来,在我的pin#new视图中,我有以下表格:

固定新视图

<%= form_for :pin, url: pins_path do |f| %>

    <div class="small-12 columns">
        <%= f.label :title %>
        <%= f.text_field :title %>
    </div>

    <div class="small-12 columns">
        <%= f.label :description %>
        <%= f.text_area :description, :rows => 10 %>
    </div>

    <div class="small-12 columns">
        <%= f.label :type %>
        <%= f.collection_select :type_id, Type.order(:title), :id, :title, include_blank: false %>
    </div>

    <div class="small-12 columns">
        <%= f.label :genres %>
        <%= f.collection_select :genre_ids, Genre.order(:title), :id, :title, {}, { :multiple => true } %>
    </div>

    <div class="small-12 columns">
        <%= f.submit "Create Pin", :class => "button" %>
    </div>

<% end %>

该视图工作正常,并从流派表格中获取可用的流派。但是,当我去保存表单时,会创建记录(pin),但是与类型的关系不是。我在这里错过了什么?没有错误被抛出,只是没有任何反应。我假设Rails应该通过与类型的引脚关联来创建这些PinGenre记录。

Pin Controller(创建)

def create

    @pin = Pin.new(pin_params)
    @pin.user_id = current_user.id
    @pin.save

    if @pin.save
        flash[:success] = "Pin successfully created"
        redirect_to @pin
    else
        flash[:warning] = @pin.errors.full_messages.to_sentence
        redirect_to :action => "new"
    end

end

private

        def pin_params

            params.require(:pin).permit(:title, :description, :type_id, :genre_ids)

        end

我需要在这里采取进一步措施吗?记录是否需要由我自己明确创建?

感谢您的帮助和耐心。我希望我已经清楚地阅读了这篇文章。 迈克尔。

Schema.rb

ActiveRecord::Schema.define(version: 0) do

  create_table "genre_pins", force: true do |t|
    t.integer "pin_id"
    t.integer "genre_id"
  end

  create_table "genres", force: true do |t|
    t.string "title", null: false
  end

  create_table "pins", force: true do |t|
    t.integer  "user_id",                                          null: false
    t.string   "title",       limit: 160,                          null: false
    t.text     "description",                                      null: false
    t.decimal  "latitude",                precision: 10, scale: 8
    t.decimal  "longitude",               precision: 11, scale: 8
    t.datetime "created_at"
    t.datetime "updated_at"
    t.datetime "deleted_at"
    t.integer  "type_id",                                          null: false
  end

  create_table "profiles", force: true do |t|
    t.integer  "user_id",                                          null: false
    t.string   "first_name",                                       null: false
    t.string   "last_name",                                        null: false
    t.string   "gender"
    t.string   "email"
    t.text     "bio"
    t.decimal  "latitude",                precision: 10, scale: 8
    t.decimal  "longitude",               precision: 11, scale: 8
    t.string   "image",      limit: 2000
    t.datetime "updated_at"
    t.datetime "created_at"
    t.datetime "deleted_at"
  end

  create_table "replies", force: true do |t|
    t.integer  "pin_id",     null: false
    t.integer  "user_id",    null: false
    t.text     "reply",      null: false
    t.datetime "updated_at"
    t.datetime "created_at"
    t.datetime "deleted_at"
  end

  create_table "saves", force: true do |t|
    t.integer  "pin_id",     null: false
    t.integer  "user_id",    null: false
    t.datetime "updated_at"
    t.datetime "created_at"
    t.datetime "deleted_at"
  end

  create_table "settings", force: true do |t|
    t.integer  "user_id",        null: false
    t.boolean  "show_email",     null: false
    t.boolean  "show_telephone", null: false
    t.integer  "timezone",       null: false
    t.datetime "updated_at"
    t.datetime "created_at"
    t.datetime "deleted_at"
  end

  create_table "types", force: true do |t|
    t.string "title", null: false
  end

  create_table "users", force: true do |t|
    t.string   "provider",         limit: 45,   null: false
    t.string   "provider_id",      limit: 45,   null: false
    t.string   "oauth_token",      limit: 1000
    t.datetime "oauth_expires_at"
    t.datetime "updated_at"
    t.datetime "created_at"
    t.datetime "deleted_at"
  end

end

生成的观看源

<form accept-charset="UTF-8" action="/pins" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="3VO3kVR/62JFf6dJs+yyPTPvYJb3fsUSLRFljSE0Jdk=" /></div>

        <div class="small-12 columns">
            <label for="pin_title">Title</label>
            <input id="pin_title" name="pin[title]" type="text" />
        </div>

        <div class="small-12 columns">
            <label for="pin_description">Description</label>
            <textarea id="pin_description" name="pin[description]" rows="10">
</textarea>
        </div>

        <div class="small-12 columns">
            <label for="pin_type">Type</label>
            <select id="pin_type_id" name="pin[type_id]"><option value="2">Available</option>
<option value="1">Wanted</option></select>
        </div>

        <div class="small-12 columns">
            <label for="pin_genres">Genres</label>
            <input name="pin[genre_ids][]" type="hidden" value="" /><select id="pin_genre_ids" multiple="multiple" name="pin[genre_ids][]"><option value="5">Ambient</option>
<option value="4">Electronic</option>
<option value="2">Indie</option>
<option value="3">Jazz</option>
<option value="6">Metal</option>
<option value="1">Rock</option></select>
        </div>

        <div class="small-12 columns">
            <input class="button" name="commit" type="submit" value="Create Pin" />
        </div>

</form>

1 个答案:

答案 0 :(得分:3)

您需要告诉您的控制器'genre_ids`应该是一个数组:

params.require(:pin).permit(:title, :description, :type_id, genre_ids: [])

但是我希望你会得到另一个错误(未知属性gener_ids)。如果发生这种情况,请告诉我。