0

我有一个作者拥有并且属于多本书的场景,反之亦然。在instructions之后建立one-to-many关系中的关联可以正常工作,但是当介绍many-to-many关系时,只要尝试创建或更新我的书籍模型,就会收到此错误消息。与Rails中的公共活动使用多对多关系

undefined method `author' for #<Book:0x007fb91ae56a70> 

至于设立的作者是如何选择一本书我使用令牌输入提供的代码railscast here有一些改变。

class Author < ActiveRecord::Base 
    has_many :authorships 
    has_many :books, through: :authorships 

    def self.tokens(query) 
     authors = where("name like ?", "%#{query}%") 
     if authors.empty? 
      [{id: "<<<#{query}>>>", name: "Add New Author: \"#{query}\""}] 
     else 
      authors 
     end 
    end 

    def self.ids_from_tokens(tokens) 
     tokens.gsub!(/<<<(.+?)>>>/) {create!(name: $1).id} 
     tokens.split(',') 
    end 
end 

class Book < ActiveRecord::Base 
    attr_reader :author_tokens 

    include PublicActivity::Model 
    tracked owner: :author 

    has_many :authorships 
    has_many :authors, through: :authorships 

    def author_tokens=(ids) 
     self.author_ids = Author.ids_from_tokens(ids) 
    end 
end 

表单视图

<%= form_for(@book) do |f| %> 
    ... 

    <div class="field"> 
    <%= f.text_field :author_tokens, label: 'Author', input_html: {"data-pre" => @book.authors.to_json} %> 
    </div> 

    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %> 
+0

@MohammadAbuShady任何想法如何根据之前讨论的一对多来完成? – 2015-04-02 17:42:54

+0

当你把它改成'has_many:authors'你失去了'author'方法并且得到了'authors'方法 – 2015-04-02 20:07:34

+0

@MohammadAbuShady完美无缺。 Piotrek提供的解决方案展示了如何在proc中选择一个作者,但目标是让他们全部完成。这可能在这种特殊情况下做到吗? – 2015-04-02 21:17:44

回答

-1
class Author < ActiveRecord::Base 
    has_many :author_books, inverse_of: :author, dependent: :destroy 
    accepts_nested_attributes_for :author_books 
    has_many :books, through: :author_books 
end 

class Book < ActiveRecord::Base 
    has_many :author_books, inverse_of: :book, dependent: :destroy 
    accepts_nested_attributes_for :author_books 
    has_many :authors, through: :author_books 
end 

class AuthorBook < ActiveRecord::Base 
    validates_presence_of :book, :author 
end 

=============视图==============

<%= form_for @book do |f| %> 
    <%= f.text_field :title %> 
    <%= f.fields_for :author_books do |f2| %> 
    <%# will look through all author_books in the form builder.. %> 
    <%= f2.fields_for :author do |f3| %> 
     <%= f3.text_field :name %> 
    <% end %> 
    <% end %> 
<% end %> 
+0

您的答案缺少设置公共活动所需的代码 – 2015-04-02 19:32:50

0

您的Book模型中没有author关系。

什么

tracked owner: :author 

确实基本上是调用您的图书实例方法author。您应该尝试:authors

但是!

这不会解决您的问题,因为owner只能是一个。所以你可以这样做:

tracked owner: proc {|_, book| book.authors.first } 

将所有者设置为书的第一作者。

+0

测试它完全按照它读取,但它当两本或更多作者被添加到书中时,问题就会出现。在活动视图中,它只会记录该书的第一作者有活动。 – 2015-04-02 21:15:35

+0

如果您想为每位作者创建一个活动,您需要通过Book实例上的'create_activity'调用manualy。 – 2015-04-08 07:58:59

+0

这个逻辑怎么看?它是通过书籍控制器完成还是通过模型中的某种回调完成? – 2015-04-08 13:49:16