N
N
No_Time2012-10-19 16:50:29
Ruby on Rails
No_Time, 2012-10-19 16:50:29

Rails HABTM relationship. How to save?

Hello!
There are 2 models:

class Hashtag < ActiveRecord::Base<br>
      has_and_belongs_to_many :photos<br>
        attr_accessible :name<br>
       ***<br>
end<br><br>
class Photo < ActiveRecord::Base<br>
       has_and_belongs_to_many :hashtags, :uniq => true<br>
       ***<br>
end<br>

join table:
def up<br>
  create_table :hashtags_photos, :id => false do |t|<br>
         t.integer :photo_id<br>
         t.integer :hashtag_id<br>
  end<br><br>
  add_index :hashtags_photos, [:photo_id, :hashtag_id], :unique => true<br>
end<br>

When creating a Photo, the following method is passed to before_safe:
def set_hashtags<br>
      text.scan(/#+/).each do |workpiece|<br>
            next if workpiece.length > 25<br>
            hashtag = Hashtag.find_by_name(workpiece)<br>
            if hashtag<br>
              hashtag.touch<br>
            else<br>
              hashtag = Hashtag.new(:name => workpiece).save!<br>
            end<br>
            hashtags << hashtag<br>
      end <br>
    end<br>

Where text is a field for Photo, which is always non-nil. Everything would be great, but it doesn't work. Throws errors like this:
ActiveRecord::AssociationTypeMismatch: Hashtag(#70309985182100) expected, got TrueClass(#70309973845700)<br>

I tried to use the first_or_initialize and first_or_create! methods, all to no avail. Apparently I just don't understand how rails works with has_and_belongs_to_many.
What is the jamb?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
arabonradar, 2012-10-19
@No_Time

hashtag = Hashtag.new(:name => workpiece).save!

The problem is in this line - save! returns TrueClass. Change new to create! and everything will work.

G
Georgy Khromchenko, 2012-10-19
@Mox

I usually explicitly declare the model for the link ( HashtagPhoto in this example)
AND do has_many and has_many :through; (not habtm) I add attr_accessor
to the model, which gives me the related data in the right form
(for example, attr_accessor :hashtags_ids (list of id or whatever else is needed in the context))
and before_save I already create links in the link table.
A bit slick, but reliable

C
Cepega, 2012-10-19
@Cepega

hashtag = Hashtag.new(:name => workpiece).save!
In this line, in my opinion, the hashtag variable gets the value true if the Hashtag is being created, or false if there was a creation error.
Replace with
hashtag = Hashtag.new(:name => workpiece)
hashtag.save!

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question