0

レッスンテーブルとタグテーブルがあります。has_many:through関係を使用して両方を関連付け、中央のテーブルはtags_relationship.rbです。

class Lesson < ActiveRecord::Base
  attr_accessible :title, :desc, :content, :tag_name
  belongs_to :user

  has_many  :tag_relationships
  has_many  :tags, :through => :tag_relationships
end

class Tag < ActiveRecord::Base
  attr_accessible :name

  has_many :tag_relationships
  has_many :lessons, :through => :tag_relationships
end

私の見解の1つでは、仮想属性を作成しようとしています。私は持っています...

    <div class="tags">
        <%= f.label :tag_name, "Tags" %>
        <%= f.text_field :tag_name, data: { autocomplete_source: tags_path} %>
    </div>

しかし、私のレッスンテーブルにはその属性tag_nameがないため、代わりに私のメソッドを呼び出します

    def tag_name
       ????????
    end

    def tag_name=(name)
        self.tag = Tag.find_or_initialize_by_name(name) if name.present?
    end

しかし、????????の中に何を入れるべきかわからない。タグテーブル内の:name属性を参照しようとしています。

当時、私はhas_manyとbelongs_toの関係を使用していました。私のレッスンはタグに属していました(これは間違っていました)が、私は書くことができました...

tag.name

そしてそれはうまくいった。しかし、そのhas_many:through nowなので、よくわかりません。tags.name、Lessons.tags.nameなどを使用してみましたが、機能しないようです。タグテーブル名属性を参照するにはどうすればよいですか?ありがとうございました

4

1 に答える 1

2

私の悪い英語をお詫びします。

あなたがレッスンLessonに所属していたときは1つしかなかったので、コードは正しかったです。しかし、今では多くのsがあり、それはコレクション(簡単な言葉で配列)です。したがって、セッターはもっと複雑でなければなりません。TagtagLessonTag

def tag_names=(names)
  names = if names.kind_of? String
    names.split(',').map{|name| name.strip!; name.length > 0 ? name : nil}.compact
  else
    names
  end

  current_names = self.tags.map(&:name) # names of current tags
  not_added = names - current_names # names of new tags
  for_remove = current_names - names # names of tags that well be removed

  # remove tags
  self.tags.delete(self.tags.where(:name => for_remove))
  # adding new
  not_added.each do |name|
    self.tags << Tag.where(:name => name).first || Tag.new(:name => name)
  end
end

そして、getterメソッドは次のようになります。

def tag_names
  self.tags.map(&:name)
end

ところで、のようなファインダーfind_by_nameは非推奨です。を使用する必要がありますwhere

于 2012-04-19T21:13:16.610 に答える