如何在ActiveRecord中保存具有多对多关系的标记

时间:2015-04-07 05:16:16

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

我尝试制作包含多对多标签的视频。因此,每个标记都是Tag表中的每一行。我不确定自己是否必须这样做,或者Rails有一些可以做到的魔法?

这是我的模特。

class Video < ActiveRecord::Base
  belongs_to :user

  has_many :video_tags
  has_many :tags, through: :video_tags
end

class Tag < ActiveRecord::Base
end

class VideoTag < ActiveRecord::Base
  belongs_to :video
  belongs_to :tag
end

这是我的表格

<%= form_for(@video, html: { class: "directUpload" }, multipart: true) do |f| %>
  <% if @video.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@video.errors.count, "error") %> prohibited this user from being saved:</h2>

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

  <div class="field">
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :path %><br>
    <%= f.file_field :path%>
  </div>
  <div class="field">
    <%= f.label :tags %><br>
    <%= f.text_field :tags %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

这是Controller

class VideosController < ApplicationController
  def show
      @videos = Video.where(user_id: params[:user_id])

  end

  def new
        @video = Video.new
    @s3_direct_post = S3_BUCKET.presigned_post(key: "uploads/#{SecureRandom.uuid}/${filename}", success_action_status: 201, acl: :public_read)
  end


  def create
    @video = Video.new(video_params)
    @video.user_id = 1
    if @video.save
        redirect_to @video
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.

    # Never trust parameters from the scary internet, only allow the white list through.
  def video_params
        params.require(:video).permit(:title, :path, :tags)
  end

end

但后来我收到了这个错误,我认为我一定错过了什么。我只是希望用空格分隔标签。

Started POST "/videos" for ::1 at 2015-04-07 00:21:11 -0400
Processing by VideosController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"authenticity_token",
     

&#34;视频&#34; = GT; {&#34;标题&#34; = GT;&#34; asdfasdf&#34 ;,   &#34;路径&#34; = GT;&#34; // s3.amazonaws.com/uploads/token/57203191c21df0cacf98f3fa9340f4.mp4" ;,   &#34;标签&#34; =&gt;&#34;测试&#34;},&#34;提交&#34; =&gt;&#34;创建视频&#34;}       在3毫秒内完成500内部服务器错误

NoMethodError (undefined method `each' for "test ":String):
  app/controllers/videos_controller.rb:14:in `create'

3 个答案:

答案 0 :(得分:1)

我的以下答案将对您有所帮助 https://stackoverflow.com/questions/22611372/rails-4-paperclip-and-polymorphic-association

您可以使用accept_nested_attributes_for

 <%= f.fields_for :tags, @_your_tags do |t| %>

而不是

<div class="field">
   <%= f.label :tags %><br>
   <%= f.text_field :tags %>
</div>

答案 1 :(得分:1)

您的关联将是这样的:

class Video < ActiveRecord::Base
  belongs_to :user

  has_many :video_tags
  has_many :tags, through: :video_tags
end

class VideoTag < ActiveRecord::Base
  belongs_to :video
  belongs_to :tag
end

class Tag < ActiveRecord::Base
  has_many :video_tags
  has_many :videos, through :video_tags
end

答案 2 :(得分:0)

我发现this wiki非常有帮助。是的rails有一种特殊的方法来处理这个问题。这些称为嵌套模型,或者您也可以使用nested_form gem