Rails:使用 jquery tokeninput (railscast #258) 创建新条目 [英] Rails : Using jquery tokeninput (railscast #258) to create new entries
问题描述
我已经成功地添加了 Ryan Bates railscast #258 中未包含的新艺术家条目 http://railscasts.com/episodes/258-token-fields
I have successfully been able to implement the addition of new artist entries which was not included in Ryan Bates railscast #258 http://railscasts.com/episodes/258-token-fields
换句话说,用户可以输入艺术家姓名,该艺术家姓名将使用 jquery tokinput 自动完成.但是,我希望自动完成结果仅显示由该个人用户创建的艺术家姓名.
So in other words, a user can enter an artist name which will autocomplete using jquery tokinput. However, I'd like the autocomplete results to only display the artist names which were created by that individual user.
这有意义吗?一个更好、更容易理解的例子是 collection.rb,用户创建帖子并指定帖子所属的集合",但他们应该只能将帖子添加到他们自己创建的集合中.
Does this make sense? An better and more understandable example would be for a collection.rb, where users create posts and specify a 'collection' for the post to belong to, but they should only be able to add posts to the collections which they created themselves.
这是带有artist_tokens 作为虚拟属性的帖子表单:
This is the post form with artist_tokens as a virtual attribute:
<%= 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 %>
这会通过在 post 表单上的 artist_tokens 字段中输入的值来查找艺术家,并且我还添加了选项添加 {params[:q]}"以添加新条目.
This finds the artist by the value entered into the artist_tokens field on the post form, and I also added the option "Add {params[:q]}" to add new entries.
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 解析新"条目,然后用它们创建一个新艺术家.然后再次分配艺术家 ID.
I added the additional code to parse the 'new' entries by id and then create a new artist with them. Then the artist_ids are assigned again.
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 存储在表中吗?我该怎么做?
Everything works great except the ability to narrow the json results by only the current_user's entries. How would I go about doing this? Do I need to store the user_id of the entries creator in the table? How can I do this?
模型关联
# 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
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 数据库条目)引用自:Rails 3:alias_method_chain 仍在使用?
Attempted alias_method_chain to set post's user_id attribute first. (didn't work to fix the NULL db entries) referneced from: 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
推荐答案
如果你不想修改模型中的任何内容,那么你可以这样做:
If you don't want to modify anything in your models, then you can do it like this:
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
注意这里有很多连接,所以不推荐.
Notice that there are a lot of joins going on here, so not recommended.
要调试为什么 Artist.create!(:name => $1, :user_id => self.user_id)
不起作用,如果我们能看到更多代码,那就太好了,特别是创建 Post
To debug why Artist.create!(:name => $1, :user_id => self.user_id)
would not work, it would be great if we can see some more code, particularly the action
to create a Post
更新:您是否尝试将 PostController#create
更改为跟随,虽然我觉得当前代码应该可以正常工作,
UPDATE: Did you try changing PostController#create
to following, although I feel curent code should work as it is,
@post = current_user.posts.build
if @post.update_attributes(params[:post])
# do something
else
# do something else
end
我不是 Rails 专业人士,不了解 alias_method_chain
,因此无法评论它为什么不起作用.
I am not a rails pro and don't understand the alias_method_chain
so can't comment on why it didn't work.
这篇关于Rails:使用 jquery tokeninput (railscast #258) 创建新条目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!