6

我已經成功地得以實施的新的藝術家條目加入其中並沒有包含在瑞安貝茨railscast#258 http://railscasts.com/episodes/258-token-fieldsRails的:使用jQuery tokeninput(railscast#258)來創建新條目

所以,換句話說,用戶可以輸入一個藝術家的名字,將使用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_ids再次分配。

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項) 從referneced: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 
+0

你剛纔提到它的'collection.rb'是什麼,但稍後會完全跳過它。 「Post」和「Artist」有什麼關係?你到底想做什麼? – rubish

+0

郵政和藝術家有一個名爲artisanships的聯合表(使用artist_ids和post_ids)。如果您熟悉jquery tokeninput,我添加了添加新條目的功能。我希望自動完成只包含用戶創建的條目。 –

+0

Collection.rb不存在這只是一個例子,以更好地理解我想如何使用jQuery的tokeninput,你可以想到集合代替藝術家。用戶創建一個帖子並鍵入一個集合名稱,如果它的新集合選擇了「添加:」新集合名稱「,如果它是一箇舊集合,他們只選擇它。如果用戶創建集合,他們只能從他們自己的集合中選擇更有意義嗎? –

回答

3

如果你不想修改你的模型話,那麼你可以做這樣的:

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

UPDATE:你有沒有嘗試改變PostController#create到下面的,雖然我覺得CURENT代碼應該工作,因爲它是

@post = current_user.posts.build 
if @post.update_attributes(params[:post]) 
    # do something 
else 
    # do something else 
end 

我不是一個軌道親和不理解alias_method_chain所以不能上,爲什麼它沒有工作發表評論。

+0

我認爲你在這裏正確的軌道上。我嘗試調試:user_id => self.user_id問題,並認爲這是由於post屬性的設置順序所致。我嘗試使用:attributes =方法上的alias_method_chain來首先在帖子上設置user_id屬性,以便在調用self.user_id時它不是NULL。這似乎沒有工作。我將用我的posts_controller.rb和我嘗試使用alias_method_chain的代碼更新上面的代碼。 –

+0

我仍然無法得到它的工作,我在其他地方讀到,這是因爲帖子只是一個紅寶石對象,直到它保存併成爲一個ActiveRecord對象,所以直到它保存它沒有一個ID。我想我需要使用accept_nested_attributes_for,但對於如何使用感到困惑。有任何想法嗎?再次感謝 –

+0

這是不正確的。它是一個'ActiveRecord'對象,只是沒有與數據庫中的任何行綁定。你可以在'@post = current_user.posts.build'這行之後放一行'puts @ post.inspect',並從控制檯發佈輸出。 – rubish

2

如果你使用像色器件,清除或authlogic一些認證的解決方案,你可能已經CURRENT_USER方法。 因此添加一列USER_ID:整數藝術家模型,並做到以下幾點:

#User model 
has_many :artists 

#Artist model 
belongs_to :user 

#Artists controller 
def index 
    @artists = current_user.artists.where("name like ?", "%#{params[:q]}%") #this answers your question! 
    ... blah blah 
end 

當然不要忘了,當你創建一個藝術家設置user_id列。

+0

嗨,感謝您的幫助,我想你已經回答了一半問題!我嘗試過用Artist.create!(:name => $ 1,:user_id = 1)來調整artist_tokens方法,但是我試圖在創建藝術家時添加user_id。 > self.user_id).id但是數據庫保持顯示NULL條目 –

+0

如何將user_id分配給控制器中的新帖子?如果在PostsController#create中執行諸如current_user.build_post(params [:post])之類的操作,那麼user_id應該是assig ned和你的嘗試應該成功。如果沒有,請重新啓動服務器。如果它沒有幫助,請將控制器代碼添加到您的問題中。 –

+0

我在上面添加了控制器代碼,但我需要將user_id添加到藝術家模型而不是後期模型。 user_id被分配到後期模型,但我無法獲得user_id分配給藝術家模型,我不斷收到空條目。 –

相關問題