This project is archived and is in readonly mode.
habtm association failure to save in join table with after_create callback.
Reported by demersus | May 7th, 2010 @ 09:40 PM
I am writing a rails app that has an attachment model that holds a reference to an uploaded file. Attachment can habtm tags. The problem I am experiencing is that Activerecord ignores the fact that I have associated tags with the attachment when I call self.save! From inside an after_create callback.
The after_create callback is necessary to save the file with the id included in the filename, and to update the file path on the record. Here is an example:
# after_create callback
def save_file
self.file_path = "#{@upload_dir}/#{self.id}_#{self.filename}"
FileUtils.copy self.file.local_path, self.file_path
self.save!
end
The after_create fires and works like it should, however - rails forgot that I had assigned tag_ids to the self.tag_ids property. (It will not perform the insert on the join table after completing the after_create callback.)
Comments and changes to this ticket
-
Neeraj Singh May 7th, 2010 @ 10:06 PM
Can you provide a sample example with complete information so that I could reproduce the problem on my side.
For example look at the way the author of this ticket has given a very clear cut way of reproducing the problem. https://rails.lighthouseapp.com/projects/8994/tickets/4329
Thanks
-
demersus May 7th, 2010 @ 10:45 PM
Sorry, I do not have a real test case for it yet. (I am new to rails and TDD in general.)
You can recreate the scenario by creating these simplified files:
attachment.rb
(attacment model)
class Attachment < ActiveRecord::Base attr_accessor :temp_file after_create :save_file has_and_belongs_to_many :tags, :uniq => true upload_dir "/some/path/to/upload/dir/" end # virtual file fields (loaded by controller.) # *not actually a column in table. def file self.temp_file end def file=(file_field) self.file_name = file_field.original_filename self.mime_type = file_field.content_type.chomp self.file_size = file_field.size.to_i # store the file field in temp_file for later processing. self.temp_file = file_field end protected # after_create callback. def save_file self.file_path = "#{upload_dir}/#{self.id}_#{self.file_name}" FileUtils.copy self.file.local_path, self.file_path self.save! end end
tag.rb
- (Tag model) *
class Tag < ActiveRecord::Base has_and_belongs_to_many :attachments, :uniq => true end
migration file
class CreateTables < ActiveRecord::Migration def self.up create_table :attachments do |t| t.string :name t.string :mime_type t.string :file_path t.string :file_name t.integer :file_size t.timestamps end create_table :tags do |t| t.string :name end create_table :attachments_tags, :id => false do |t| t.references :attachment t.references :tag end end # add self down code here end
Now, I am not going to post the view code, but here are the params that I am posting up:
attachment[name] = testfile attachment[file] = <standard file from file field in view> attachment[tag_ids][] = 1 attachment[tag_ids][] = 2
Assuming my attachments controller has a create method like this:
def create @attachment = Attachment.new params[:attachment] if @attachment.save
flash[:notice] = 'Attachment saved.' redirect_to some_restful_path()
elseflash.now[:warning] = 'Attachment failed to save.' render :new
end end
You would expect to look in your database after performing this action and see this table:
[attachments_tags]| attachment_id | tag_id | | 1 | 1 | | 1 | 2 |
But you don't. Its empty.
* the model saves the file, and updates the record in the {attachments} table correctly. But the tag_ids are completely ignored. - (Tag model) *
-
demersus May 7th, 2010 @ 10:50 PM
- Tag changed from activerecord callback habtm save to 2.3.x, activerecord, after_create, habtm, save
-
Santiago Pastorino February 2nd, 2011 @ 05:02 PM
- State changed from new to open
- Tag changed from 2.3.x, activerecord, after_create, habtm, save to 23x, activerecord, after_create, habtm, save
This issue has been automatically marked as stale because it has not been commented on for at least three months.
The resources of the Rails core team are limited, and so we are asking for your help. If you can still reproduce this error on the 3-0-stable branch or on master, please reply with all of the information you have about it and add "[state:open]" to your comment. This will reopen the ticket for review. Likewise, if you feel that this is a very important feature for Rails to include, please reply with your explanation so we can consider it.
Thank you for all your contributions, and we hope you will understand this step to focus our efforts where they are most helpful.
-
Santiago Pastorino February 2nd, 2011 @ 05:02 PM
- State changed from open to stale
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>