6

he podido con éxito para poner en práctica la adición de nuevas entradas artista que no fue incluido en Ryan Bates Railscast # 258 http://railscasts.com/episodes/258-token-fieldsRieles: Usando tokeninput jQuery (Railscast # 258) para crear nuevas entradas

Así, en otras palabras, un usuario puede ingresar un nombre de artista que se autocompletará usando jquery tokinput. Sin embargo, me gustaría que los resultados de autocompletar solo muestren los nombres de los artistas que fueron creados por ese usuario individual.

¿Tiene esto sentido? Un ejemplo mejor y más comprensible sería un collection.rb, donde los usuarios crean publicaciones y especifican una "colección" para la publicación a la que pertenecen, pero solo deberían poder agregar publicaciones a las colecciones que ellos mismos crearon.

Ésta es la forma post con artist_tokens como un atributo virtual:

<%= 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 %> 

Esto encuentra el artista por el valor introducido en el campo artist_tokens en el formulario de correo, y también añade la opción "Añadir {params [: q]} "para agregar nuevas entradas.

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 

Agregué el código adicional para analizar las 'nuevas' entradas por id y luego crear un nuevo artista con ellas. Luego los artist_ids se asignan nuevamente.

post.rb 
def artist_tokens=(ids) 
    ids.gsub!(/CREATE_(.+?)_END/) do 
     Artist.create!(:name => $1).id 
    end 
    self.artist_ids = ids.split(",") 
    end 

Todo funciona muy bien, excepto la capacidad de reducir los resultados JSON por sólo las entradas del CURRENT_USER. ¿Cómo voy a hacer esto? ¿Debo guardar el user_id del creador de las entradas en la tabla? ¿Cómo puedo hacer esto?

EDIT: asociaciones para modelos

# 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 

EDIT: 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 

Editar: Intento de alias_method_chain para establecer el atributo user_id del mensaje es el primero. (No funcionó arreglar las entradas nulo DB) referneced de: 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

¿Qué es 'collection.rb' que lo mencionó anteriormente, pero lo omitió por completo más tarde. ¿Cómo se relacionan 'Post' y' Artist'? ¿Qué es exactamente lo que quiere hacer? – rubish

+0

La publicación y el artista tienen una tabla unida llamada artesanías (que usa artist_ids y post_ids). Si está familiarizado con jquery tokeninput, agregué la posibilidad de agregar nuevas entradas. Me gustaría que la autocompletación solo incluya las entradas creadas por el usuario. –

+0

Collection.rb no existe. Es solo un ejemplo para comprender mejor cómo me gustaría usar jquery tokeninput, puede pensar en colecciones en lugar de artistas. Un usuario crea una publicación y escribe un nombre de colección, si es una colección nueva seleccionan "agregar:" nuevo nombre de colección "si es una colección anterior, simplemente la seleccionan. Si un usuario crea una colección, solo puede seleccionar su propia colección. colecciones. ¿Tiene más sentido? –

Respuesta

3

Si no desea modificar nada en sus modelos, a continuación, puede hacerlo de esta manera:

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 

en cuenta que hay una gran cantidad de combinaciones pasando aquí, por lo que no se recomienda.

para depurar qué Artist.create!(:name => $1, :user_id => self.user_id) no quiere trabajar, que sería genial si podemos ver algo más de código, en particular la action para crear una ACTUALIZACIÓN Post

: ¿Has intentado cambiar PostController#create al siguiente, aunque me siento código curent debería funcionar como es,

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

no soy un raíles a favor y no entiendo la alias_method_chain así que no puedo comentar por qué no funcionó.

+0

Creo que estás en el camino correcto aquí. Intenté depurar el problema the: user_id => self.user_id y pensé que era debido al orden en que se establecieron los atributos de la publicación. Intenté usar alias_method_chain en el método: attributes = para establecer primero el atributo user_id en la publicación, por lo que cuando se llamó a self.user_id, no fue NULL. Esto no pareció funcionar. Actualizaré el código anterior con mis posts_controller.rb y el código que probé usando alias_method_chain. –

+0

Todavía no puedo hacer que funcione, leí en otro lugar que esto se debe a que la publicación es solo un objeto ruby ​​hasta que se guarda y se convierte en un objeto ActiveRecord, por lo que hasta su guardado no tiene una identificación. Creo que necesito usar accept_nested_attributes_for pero estoy confundido sobre cómo. ¿Algunas ideas? Gracias de nuevo –

+0

Eso no es verdad. Es un objeto 'ActiveRecord', simplemente no está relacionado con ninguna fila en la base de datos. ¿Puede poner una línea adicional 'puts @ post.inspect' después de la línea' @post = current_user.posts.build' y publicar el resultado de la consola. – rubish

2

si está utilizando alguna solución de autenticación como legado, el despacho o authlogic, es probable que ya tiene current_user método. Por lo tanto agregar una columna user_id: número entero al modelo del artista y hacer lo siguiente:

#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 

Y, por supuesto, no se olvide de establecer la columna user_id cuando se crea un artista.

+0

Hola, gracias por la ayuda. ¡Creo que está a punto de responder mi pregunta! he tratado infructuosamente de llenar la columna user_id para el modelo de artista. ¿Podría explicar cómo agregaría el user_id cuando creo un artista? Intenté ajustar el método artist_tokens con Artist.create! (: name => $ 1,: user_id = > self.user_id) .id pero el db sigue mostrando entradas NULL –

+0

¿Cómo se asigna user_id a una nueva publicación en el controlador? Si se hace algo como current_user.build_post (params [: post]) en PostsController # create, entonces user_id debería ser assig ned y su intento debería tener éxito. Si no es así, reinicie su servidor. Si no ayuda, agregue código de controlador a su pregunta. –

+0

He agregado el código de controlador anterior, pero necesito ayuda para agregar el user_id al modelo de artista, no al modelo de publicación. El user_id está asignado al modelo de publicación, pero no puedo obtener el user_id para asignarlo al modelo de artista. Sigo obteniendo entradas nulas. –

Cuestiones relacionadas