Reputation: 447
Thanks for any help in advance.
I would like to set id3 tag data in my database as attributes for my model MasterSong. Specifically, title, artist, and album.
create_table :master_songs do |t|
t.integer :user_id
t.has_attached_file :m_song
**- t.string :title
- t.string :artist
- t.string :album**
In my model I'm using a callback to set the data before the object(master_song) is saved.
before_save :set_id3_tags_in_database
def set_id3_tags_in_database
TagLib::MPEG::File.open(self.m_song.path) do |file|
tag = file.id3v2_tag
tag.title
tag.album
tag.artist
end
self.update_attributes(:title => tag.title,
:artist => tag.artist,
:album => tag.album)
end
I'm pretty sure my syntax is the problem. The object seems to hit an error
undefined method `title' for nil:NilClass with an infinite loop
Controller create action is normal:
def create
@master_song = current_user.master_songs.build(params[:master_song])
respond_to do |format|
if @master_song.save
format.html { redirect_to @master_song, notice: 'Master song was successfullycreated.' }
end
What am I doing wrong here? Update: def set_id3_tags z = TagLib::MPEG::File.open(self.m_song.path) do |file| tag = file.id3v2_tag tag.title end self.update_attribute!(:title => z) end
get stack level too deep error now.
Upvotes: 1
Views: 1075
Reputation: 447
OK! So I did it, after playing and playing and playing.
def set_id3_tags
z = TagLib::MPEG::File.open(self.m_song.path) do |file|
unless tag.nil?
tag = file.id3v2_tag
self.title = tag.title
self.album = tag.album
self.artist = tag.artist
else
end
end
Adding the if title.nil? did it for me. Callbacks are weird but definitely valuable. Hope this helps someone else.
Upvotes: 1
Reputation: 31407
First of all, ensure that self.m_song.path
is the right path and that a file exists there.
Next, the following line:
tag = file.id3v2_tag
Doesn't create a tag when the file does not yet have a tag, and therefore may return nil. Set the optional parameter "create" to true for it to automatically create a tag:
tag = file.id3v2_tag(true)
Ok, then it appears that you would want to save the tag data after you have set it. For that you have to explicitly call save, like this (notice the last line of the block):
TagLib::MPEG::File.open(self.m_song.path) do |file|
tag = file.id3v2_tag(true)
# set data
file.save
end
For more information, please see the documentation here: http://rubydoc.info/gems/taglib-ruby/frames
Upvotes: 6