我已经成功地实现了新艺术家歌手条目的添加,该条目未包含在Ryan Bates railscast#258 http://railscasts.com/episodes/258-token-fields中
因此,换句话说,用户可以输入艺术家名称,该名称将使用jquery tokinput自动完成。但是,我希望自动完成结果仅显示由该个人用户创建的艺术家姓名。
这有意义吗?一个更好的和更易理解的示例是collection.rb,用户在其中创建帖子并为该帖子所属的类别指定“收藏集”,但他们只能将帖子添加到自己创建的收藏集中。
这是带有artist_tokens作为虚拟属性的帖子形式:
<%= form_for @post, :validate => true, :html => {:multipart => true} do |f| %>
<%= render 'shared/error_messages', :object => f.object %>
<div class="field">
<%= f.label :title, 'Title:' %><br />
<%= f.text_field :title %><br />
<%= f.label :artist_tokens, "Artists" %><br />
<%= f.text_field :artist_tokens, "data-pre" =>
@post.artists.map(&:attributes).to_json %>
</div>
<div class="actions">
<%= f.submit "Submit" %>
</div>
<% end %>
这将通过在张贴表单上的artist_tokens字段中输入的值来查找艺术家,并且我还添加了选项“添加{params [:q]}”以添加新条目。
class ArtistsController < ApplicationController
def index
@artists = Artist.where("name like ?", "%#{params[:q]}%")
results = @artists.map(&:attributes)
results << {:name => "Add: #{params[:q]}", :id => "CREATE_#{params[:q]}_END"}
respond_to do |format|
format.html
format.json { render :json => results }
end
end
我添加了其他代码以按ID解析"new"条目,然后使用它们创建新的艺术家。然后再次分配artist_id。
post.rb
def artist_tokens=(ids)
ids.gsub!(/CREATE_(.+?)_END/) do
Artist.create!(:name => $1).id
end
self.artist_ids = ids.split(",")
end
除了能够仅通过current_user的条目来缩小json结果的功能之外,其他所有功能都非常有效。我将如何去做呢?我是否需要在表中存储条目创建者的user_id?我怎样才能做到这一点?
编辑:模型的关联
# app/models/user.rb
class User < ActiveRecord::Base
has_many :posts
has_many :artists, :through => :posts
end
# app/models/post.rb
class Post < ActiveRecord::Base
belongs_to :user
has_many :artisanships
has_many :artists, :through => :artisanships
end
# all/models/artist.rb
class Artist < ActiveRecord::Base
has_many :artisanships
has_many :users, :through => :artisanships
has_many :posts, :through => :artisanships
end
# app/models/artisanship.rb
class Artisanships < ActiveRecord::Base
belongs_to :post
belongs_to :artist
has_one :user, :through => :post
end
编辑:posts_controller.rb
class PostsController < ApplicationController
before_filter :authenticate_user!, :only => [:create, :edit, :update, :destroy]
before_filter :authorized_user, :only => [:destroy, :edit, :update]
def create
@user = current_user
@post = current_user.posts.build(params[:post])
if @post.save
flash[:success] = "Post created!"
redirect_to root_path
else
@feed_items = current_user.feed.paginate(:per_page => "10", :page => params[:page])
render 'pages/home'
end
end
def index
@posts = Post.paginate(:page => params[:page])
end
def show
@post = Post.find(params[:id])
end
def edit
@post = Post.find(params[:id])
end
def update
@post = Post.find(params[:id])
respond_to do |format|
if @post.update_attributes(params[:post])
format.html { redirect_to(post_path(@post), :notice => 'Post was successfully updated.') }
else
format.html { render :action => "edit" }
end
end
end
def destroy
@post.destroy
redirect_to root_path
end
def likers
@title = "Likers"
@post = Post.find(params[:id])
@likers = @post.likers.paginate(:page => params[:page])
render 'show_likers'
end
def search
if params[:q]
query = params[:q]
@search = Post.search do
keywords query
end
@posts = @search.results
end
end
private
def authorized_user
@post = Post.find(params[:id])
redirect_to root_path unless current_user?(@post.user)
end
编辑:尝试alias_method_chain首先设置帖子的user_id属性。 (无法修复NULL db条目)
引用自:Rails 3: alias_method_chain still used?
def attributes_with_user_id_first=(attributes = {})
# Make sure not to accidentally blank out the important_attribute when none is passed in
if attributes.include?(:user_id)
self.user_id = attributes.delete(:user_id)
end
self.attributes_without_user_id_first = attributes
end
alias_method_chain :attributes=, :user_id_first
最佳答案
如果您不想修改模型中的任何内容,则可以这样做:
def index
@artists = current_user.posts.join("artisianships").join("artists").
where("artisianships.post_id = posts.id").
where("artists.name like ?", "#{params[:q]}").
select("artists.name as name, artists.id as id")
results = @artists.map(&:attributes)
results << {:name => "Add: #{params[:q]}", :id => "CREATE_#{params[:q]}_END"}
respond_to do |format|
format.html
format.json { render :json => results }
end
end
请注意,这里有很多联接,因此不建议这样做。
要调试为什么
Artist.create!(:name => $1, :user_id => self.user_id)
无法正常工作,如果可以看到更多代码,特别是创建action
的Post
,那将是很棒的更新:您是否尝试将
PostController#create
更改为以下内容,尽管我认为当前代码应该可以正常工作,@post = current_user.posts.build
if @post.update_attributes(params[:post])
# do something
else
# do something else
end
我不是Rails专业人士,也不了解
alias_method_chain
,因此无法评论为什么它不起作用。关于sql - Rails : Using jquery tokeninput (railscast #258) to create new entries,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6727183/