我已成功实现了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解析“新”条目,然后使用它们创建新的艺术家。然后再次分配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仍在使用吗?
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
Artist.create!(:name => $1, :user_id =>self.user_id)
action
Post
更新:您是否尝试过更改PostController#create为以下内容,尽管我认为当前代码应该可以正常工作,
PostController#create
@post = current_user.posts.build if @post.update_attributes(params[:post]) # do something else # do something else end
我不是Rails专业人士,也不了解该功能,alias_method_chain因此无法评论为什么它不起作用。
alias_method_chain