【发布时间】:2015-10-22 17:41:55
【问题描述】:
我正在构建一个 Rails 应用程序,使用 devise 进行身份验证,使用 cancan 进行授权。我有一个表格,您可以在其中创建一个“帖子”,每个帖子都有许多“标签”。
我想创建一个类似于堆栈溢出的标签创建系统,其中标签只需通过单个文本框输入,然后在服务器端转换为适当的标签对象。最初我只是有一个文本框,我可以在其中输入一个字符串,然后该字符串将在控制器中被解析
@post.tags << params[:post][:tags].split(' ').map{ |name| Tag.createOrReturnExisting name}
而且效果很好..直到我添加了cancan授权,这需要我添加
def post_params
params.require(:post).permit(:title,:description,:tags,:content,:types_id)
end
到我的控制器,现在这会导致在尝试创建帖子时引发以下错误undefined method each for "Tag1 Tag2 Tag3\r\n":String 我假设这是因为它试图在我之前将文本框中的字符串视为标签数组有机会格式化它。
所以我的问题是,我必须如何格式化我的控制器、模型或视图才能在字符串到达 post_params 方法之前对其进行解析?
这是我的模型、视图和控制器
标签模型
class Tag < ActiveRecord::Base
has_and_belongs_to_many :post, join_table: 'tag_posts'
def self.createOrReturnExisting title
if Tag.any? {|tag| tag.title == title}
logger.debug "Tag: #{title} already exists"
Tag.find_by title: title
else
logger.debug "Tag: #{title} created"
Tag.new title: title
end
end
end
后模型
class Post < ActiveRecord::Base
belongs_to :user
has_and_belongs_to_many :tags, join_table: 'tags_posts'
has_one :type
validates :title, presence: true, length: { maximum: 50 }
validates :description, presence: true, length: { maximum: 255 }
validates :types_id, presence: true, length: { maximum: 255 }
end
new.html.erb
<h1>Post#new</h1>
<p>Find me in app/views/post/new.html.erb</p>
<%= form_for @post do |f| %>
Title: <%= f.text_field :title %>
Description: <%= f.text_area :description %>
Type: <%= f.collection_select( :types_id, Type.all, :id, :title ) %>
Content: <%= f.text_area :content%>
Tags: <%= f.text_area :tags%>
<%= f.submit %>
<% end %>
后控制器
class PostsController < ApplicationController
load_and_authorize_resource
def miniList
render 'miniList'
end
def create
@post = Post.new
@post.title = params[:post][:title]
@post.description = params[:post][:description]
@post.content = params[:post][:content]
@tagStrings = params[:post][:tags].split(' ')
puts @tagStrings
@tagStrings.map do |name|
@tags << Tag.createOrReturnExisting name
end
@post.tags = @tags
@post.types_id = params[:post][:types_id]
if @post.save!
flash[:success] = "Post Saved Successfully"
else
flash[:error] = "Post not saved"
end
current_user.posts << @post
redirect_to :root
end
def new
@post = Post.new
render 'new'
end
def edit
end
def update
end
def delete
end
private
def post_params
params.require(:post).permit(:title,:description,:tags,:content,:types_id)
end
end
【问题讨论】:
-
在您的错误中,引用了哪一行?来自哪个文件?
-
错误没有引用我的任何代码(至少它不在堆栈跟踪中)它引用
activerecord (4.2.4) lib/active_record/associations/collection_association.rb:365:in 'replace'但我确定它是 post_params 方法的结果,因为当我删除那和罐头认证,一切正常 -
您能否将
<<的行拆分为多个步骤并在其中添加一些puts以显示沿途每一步的数组状态?比如array = params[:post][:tags].split(' ')然后puts array? -
另外我想知道你是否可以只使用
@post.tags =而不是<<。因为它是创建的,所以不会有任何已经存在的标签。 -
其实...我完全改变了我的想法。你实际上并没有使用
post_params进行批量分配,所以干脆杀了它。这行得通吗?
标签: ruby-on-rails ruby devise cancan