Reputation: 851
I'm sending a base64 encoded image string to my rails server via my ios app. I'm trying to take the image in rails and save it to the database. The file is a header_img which I'm adding to my model Group.
I have been following this tutorial.
I get an undefined method error 'original_filename' but as I'm unfamiliar with the process am struggling to what it is I'm doing wrong.
The error is occuring on two lines according to the heroku log. The lines are:
Create Method:
upload_header_img(header_img)
Upload_header_img Method:
extension = File.extname(header_img_io.original_filename)
Here is my full code:
Private function at the bottom of groups_controller:
private
def upload_header_img(header_img_io)
# upload to the exact location account id and extension
extension = File.extname(header_img_io.original_filename)
# rails take public as root directory
# under the root directory (public)
# there are a icon directory
header_img_url = "/header_img/"[email protected]_s + extension
# open in binary mode
File.open("public"+icon_url,'wb') do |file|
file.write(header_img_io.read)
end
@group.update_attribute(:header_img_url, header_img_url)
end
My create groups function in the groups_controller:
def create
@group = Group.new(params[:group])
@group.owner_id = @user.id
header_img = @group.header_img || @group.decode_header_img_image_data
if header_img.present?
upload_header_img(header_img)
end
respond_to do |format|
if @group.save
@membership = @user.memberships.build(group_id: @group.id)
@membership.save
format.html { redirect_to @group, notice: 'Group was successfully created.' }
format.json { render json: @group, status: :created, location: @group }
else
format.html { render action: "new" }
format.json { render json: @group.errors, status: :unprocessable_entity }
end
end
end
Group Model :
class Group < ActiveRecord::Base
attr_accessible :description, :name, :user_id, :private, :header_img_url, :header_img_data, :header_img
attr_accessor :header_img_data, :header_img
has_many :posts
has_many :memberships
has_many :users, :through => :memberships
acts_as_followable
def decode_header_img_data
# if the icon_image_data is set
# decode it and handle by controller method
if self.header_img_data.present?
data = StringIO.new(Base64.decode64(self.header_img_data))
data.class.class_eval {attr_accessor :original_filename, :content_type}
data.original_filename = self.id.to_s+".png"
data.content_type = "image/png"
return data
end
end
end
Here is my heroku log (didn't include base64 string data as it's huge):
2014-04-04T21:30:40.892198+00:00 app[web.1]: Completed 500 Internal Server Error in 31.4ms
2014-04-04T21:30:40.922539+00:00 app[web.1]:
2014-04-04T21:30:40.922539+00:00 app[web.1]: NoMethodError (undefined method `original_filename' for #<String:0x007fa84e4c8648>):
2014-04-04T21:30:40.922539+00:00 app[web.1]: app/controllers/groups_controller.rb:91:in `upload_header_img'
2014-04-04T21:30:40.922539+00:00 app[web.1]: app/controllers/groups_controller.rb:44:in `create'
Any help is massively appreciated. Thanks.
Upvotes: 1
Views: 3037
Reputation: 6948
The problem is with your header_img_url
variable:
header_img_url = "/header_img/"[email protected]_s + extension # open in binary mode File.open("public"+icon_url,'wb') do |file| file.write(header_img_io.read) end
You changed the variable from icon_url
to header_img_url but missed updating this snippet:
File.open("public"+icon_url,'wb') do |file|
Change it to header_img_url
and you'll be good.
Also move this code:
header_img = @group.header_img || @group.decode_header_img_data if header_img.present? upload_header_img(header_img) end
after if @group.save
in your create action.
Since your @group object is not saved in the database yet, @group.id will be nil and when you call to_s on it, it will return "". Now, your header_img_url is set as "/header_img/public/", which is a directory and you'll end up reading a directory instead of a file.
Upvotes: 1