2010-11-22 19 views
2

我有一个关于多对多关系的问题,特别是has_many:通过关联。如何使用has_many:through关联来更新连接模型?

我发现的所有教程只是为您设置了模型和迁移,但在涉及到控制器的时候会让您挂起。

我想要做的是当已经存在的文章再次被添加时更新连接表的时间戳,以便它移动到“列表”的顶部。我怎么做?

这是我创造的动作看起来像:

def create 
    @article = Article.find_or_create_by_url(params[:article]) 
    if current_user.articles.find(@article) 

     # update the timestamps on the join table 
     # ie moved the old article to the top 

     flash[:notice] = "Successfully added article (again)." 
     redirect_to @article 
    else 
    @article.users << current_user 
    if @article.save 
     flash[:notice] = "Successfully added article." 
     redirect_to @article 
    else 
     render :action => 'new' 
    end 
    end 
end 

提前感谢!

更新:

@Ben李

谢谢您的回答,因为我有过相关联的的has_many我的文章模型是这样的:

has_many :readinglist_items, :dependent => :destroy 
has_many :users, :through => :readinglist_items 

,所以我不知道我是否可以将一个:touch => true添加到has_many,因为我只想在连接表中进行特定的输入。

创建操作中更新的要点是,如果用户添加了过去已添加的文章,则会将文章移动到顶部(而不是再次添加)。

回答

1

我解决了它! (readinglist_item是连接表的名称):

def create 
    @article = Article.find_or_create_by_url(params[:article]) 
    if current_user.articles.find(@article) 

     @article.readinglist_items.find_by_user_id(current_user.id).touch 

     flash[:notice] = "Successfully added article (again)." 
     redirect_to @article 
    else 
    @article.users << current_user 
    if @article.save 
     flash[:notice] = "Successfully added article." 
     redirect_to @article 
    else 
     render :action => 'new' 
    end 
    end 
end 
+0

请注意,只有将连接表设置为常规create_table类型并因此具有作为主键的id列时,readinglist_items记录上的.touch才会起作用。如果您使用create_join_table设置联接,那么您将没有主键,因此您无法触摸该记录。答案是通过进一步的迁移添加主键: add_column:readinglist_items,:id,:primary_key,first:true – IrishDubGuy 2017-10-03 23:49:07

3

如果我正确理解你,这不是控制器问题,而是一个模型问题。您可以在belongs_to关系中指定:touch => true。这将使得每当孩子更新时,协会的update_at都会更新。

所以把这样的事情在你的Article型号:

belongs_to :whatever, :touch => true 

而且,切向相关的:它不是从什么你的代码是做代码清晰,但似乎,也许你是把createupdate功能都在create方法中,而不是适当地分割它们。

+0

回答了我的问题,因为评论中的格式不好。 – Alfred 2010-11-22 18:51:25

相关问题