Rails form to upload a file to directory - undefined method - ruby-on-rails

I'm trying to create a form that uploads a pdf and an image to a directory. I currently have this code, which i've copied off a working example:
def resources_addprocess
r = Resource.new
r.title = params[:title]
r.reference = params[:reference]
r.description = params[:description]
r.campaign = params[:campaign]
r.resourcetype = params[:resourcetype]
uploaded_io = params[:file]
File.open(Rails.root.join('public','resources', uploaded_io.original_filename), 'wb') do |file|
file.write(uploaded_io.read)
end
if params[:preview].present?
uploaded_io2 = params[:preview]
File.open(Rails.root.join('app','assets','images','preview', 'resources', uploaded_io2.original_filename), 'wb') do |file|
file.write(uploaded_io2.read)
end
r.preview = uploaded_io2.original_filename
end
r.file = uploaded_io.original_filename
if r.save
flash[:success] = "You successfully added a resource."
redirect_to "/cms/resources"
else
flash[:error] = "resource wasn't successfully."
redirect_to "/cms/resources"
end
end
But I get the following error: undefined method 'original_filename' This worked on a different project.. not sure why it isn't now?

Found the answer just after posting this,
Turns out if you use the =form_tag you need to define it's multipart..
http://guides.rubyonrails.org/form_helpers.html#uploading-files

Related

undefined method `original_filename' for nil:NilClass

I'm trying to upload a file to an email as attachment.When i try to upload, i have an error
"undefined method `original_filename' for nil:NilClass" What i'm doing wrong?
I need to catch the file from the controller,and handle the exception if params[:file] not present?
In my view, there's simple upload file tag
%strong Send Email with PDF attachment:
= file_field_tag :file
I need to catch the file from the controller,
This is my controller..
#name = params[:file].original_filename
if params[:file].present?
directory = "public/data"
path = File.join(directory, #name)
uniq_name = (0...10).map {(65 + rand(26)).chr}.join
time_footprint = Time.now.to_formatted_s(:number)
File.open(path, "wb") do |file|
file.write(params[:file].read)
#uniq_path = File.join(directory, uniq_name + time_footprint + File.extname(file))
File.rename(file, #uniq_path)
end
else
flash[:notice] = "You are going to send email without the invoice"
redirect_to update_estimate_job_final_invoices_path(#ticket)
end
The first line is #name = params[:file].original_filename. If params[:file] is not present then the call to original_filename will fail. Move that line inside the if statement:
if params[:file].present?
#name = params[:file].original_filename
directory = "public/data"
path = File.join(directory, #name)
...
else
...
end

Save to database post,but before check http request in Ruby on Rails

I am trying save hashes to my database but before I want check request
I am using
require 'net/http'
gem 'http'
This is my controller (hashes I call :hammer)
class PaymentsController < ApplicationController
before_action :logged_in_user, only: [:create]
def create
#payment = current_user.payments.build(payment_params)
aza = ''
uri = URI("https://blockexplorer.com/api/tx/#{:hammer}")
res = Net::HTTP::Post.new(uri)
res1 = res.class.name
aza += Net::HTTP.get(uri)
#go = aza
if aza.include?( '3MGeicHK6P2pUpepsXyTiuA7omMbRZbZx3') #'"addresses":["3MGeicHK6P2pUpepsXyTiuA7omMbRZbZx3"]'
if aza.include? '"value":"0.03072025"'
if aza.include? '"confirmations":0'
flash[:info] = "Wait 15 minutes for confirm"
else
if #payment.save
flash[:success] = "You paid"
redirect_to root_url
else
render 'welcome/index'
end
end
else
flash[:danger] = "You paid less"
end
else
flash[:danger] = "#{res1}"
redirect_to root_url
end
end
def destroy
end
private
def payment_params
params.require(:payment).permit(:hammer)
end
end
When I was try to save it is not check, it is just show error 400
But If I use console it is work
uri = URI("https://blockexplorer.com/api/tx/f484f14ebf9726ab2ab46ffc491786db50fc69ceff737620122e51559a3ea379")
irb(main):003:0> Net::HTTP.get(uri)
I find want can to do
#test = payment_params[:hammer]
# hammer = ''
# hammer += params[:hammer].to_s
aza = ''
uri = URI("https://blockexplorer.com/api/tx/#{#test}")
I think the bug is there:
uri = URI("https://blockexplorer.com/api/tx/#{:hammer}")
in PaymentsController.
Try that instead:
uri = URI("https://blockexplorer.com/api/tx/#{params[:hammer]}")
You missed params[] in your interpolation.

How to get XML doc from downloaded zip file in rails

I have used Typhoeus to stream a zip file to memory, then am iterating through each file to extract the XML doc. To read the XML file I used Nokogiri, but am getting an error, Errno::ENOENT: No such file or directory # rb_sysopen - my_xml_doc.xml.
I looked up the error and saw that ruby is most likely running the script in the wrong directory. I am a little confused, do I need to save the XML doc to memory first before I can read it as well?
Here is my code to clarify further:
Controller
def index
url = "http://feed.omgili.com/5Rh5AMTrc4Pv/mainstream/posts/"
html_response = Typhoeus.get(url)
doc = Nokogiri::HTML(html_response.response_body)
path_array = []
doc.search("a").each do |value|
path_array << value.content if value.content.include?(".zip")
end
path_array.each do |zip_link|
download_file = File.open zip_link, "wb"
request = Typhoeus::Request.new("#{url}#{zip_link}")
binding.pry
request.on_headers do |response|
if response.code != 200
raise "Request failed"
end
end
request.on_body do |chunk|
download_file.write(chunk)
end
request.run
Zip::File.open(download_file) do |zipfile|
zipfile.each do |file|
binding.pry
doc = Nokogiri::XML(File.read(file.name))
end
end
end
end
file
=> #<Zip::Entry:0x007ff88998373
#comment="",
#comment_length=0,
#compressed_size=49626,
#compression_method=8,
#crc=20393847,
#dirty=false,
#external_file_attributes=0,
#extra={},
#extra_length=0,
#filepath=nil,
#follow_symlinks=false,
#fstype=0,
#ftype=:file,
#gp_flags=2056,
#header_signature=009890,
#internal_file_attributes=0,
#last_mod_date=18769,
#last_mod_time=32626,
#local_header_offset=0,
#local_header_size=nil,
#name="my_xml_doc.xml",
#name_length=36,
#restore_ownership=false,
#restore_permissions=false,
#restore_times=true,
#size=138793,
#time=2016-10-17 15:59:36 -0400,
#unix_gid=nil,
#unix_perms=nil,
#unix_uid=nil,
#version=20,
#version_needed_to_extract=20,
#zipfile="some_zip_file.zip">
This is the solution I came up with:
Gems:
gem 'typhoeus'
gem 'rubyzip'
gem 'redis', '~>3.2'
Controller:
def xml_to_redis_list(url)
html_response = Typhoeus.get(url)
doc = Nokogiri::HTML(html_response.response_body)
#redis = Redis.new
path_array = []
doc.search("a").each do |value|
path_array << value.content if value.content.include?(".zip")
end
path_array.each do |zip_link|
download_file = File.open zip_link, "wb"
request = Typhoeus::Request.new("#{url}#{zip_link}")
request.on_headers do |response|
if response.code != 200
raise "Request failed"
end
end
request.on_body do |chunk|
download_file.write(chunk)
end
request.run
while download_file.size == 0
sleep 1
end
zip_download = Zip::File.open(download_file.path)
Zip::File.open("#{Rails.root}/#{zip_download.name}") do |zip_file|
zip_file.each do |file|
xml_string = zip_file.read(file.name)
check_if_xml_duplicate(xml_string)
#redis.rpush("NEWS_XML", xml_string)
end
end
File.delete("#{Rails.root}/#{zip_link}")
end
end
def check_if_xml_duplicate(xml_string)
#redis.lrem("NEWS_XML", -1, xml_string)
end

Gem Resque Error - Undefined "method perform" after Overriding it form the super class

First of all Thanks for you all for helping programmers like me with your valuable inputs in solving day to day issues.
This is my first question in stack overflow as I am experiencing this problems from almost one week.
WE are building a crawler which crawls the specific websites and extract the contents from it, we are using mechanize to acheive this , as it was taking loads of time we decided to run the crawling process as a background task using resque with redis gem , but while sending the process to background I am experiencing the error as the title saying,
my code in lib/parsers/home.rb
require 'resque'
require File.dirname(__FILE__)+"/../index"
class Home < Index
Resque.enqueue(Index , :page )
def self.perform(page)
super (page)
search_form = page.form_with :name=>"frmAgent"
resuts_page = search_form.submit
total_entries = resuts_page.parser.xpath('//*[#id="PagingTable"]/tr[2]/td[2]').text
if total_entries =~ /(\d+)\s*$/
total_entries = $1
else
total_entries = "unknown"
end
start_res_idx = 1
while true
puts "Found #{total_entries} entries"
detail_links = resuts_page.parser.xpath('//*[#id="MainTable"]/tr/td/a')
detail_links.each do |d_link|
if d_link.attribute("class")
next
else
data_page = #agent.get d_link.attribute("href")
fields = get_fields_from_page data_page
save_result_page page.uri.to_s, fields
#break
end
end
site_done
rescue Exception => e
puts "error: #{e}"
end
end
and the superclass in lib/index.rb is
require 'resque'
require 'mechanize'
require 'mechanize/form'
class Index
#queue = :Index_queue
def initialize(site)
#site = site
#agent = Mechanize.new
#agent.user_agent = Mechanize::AGENT_ALIASES['Windows Mozilla']
#agent.follow_meta_refresh = true
#rows_parsed = 0
#rows_total = 0
rescue Exception => e
log "Unable to login: #{e.message}"
end
def run
log "Parsing..."
url = "unknown"
if #site.url
url = #site.url
log "Opening #{url} as a data page"
#page = #agent.get(url)
#perform method should be override in subclasses
#data = self.perform(#page)
else
#some sites do not have "datapage" URL
#for example after login you're already on your very own datapage
#this is to be addressed in 'perform' method of subclass
#data = self.perform(nil)
end
rescue Exception=>e
puts "Failed to parse URL '#{url}', exception=>"+e.message
set_site_status("error "+e.message)
end
#overriding method
def self.perform(page)
end
def save_result_page(url, result_params)
result = Result.find_by_sql(["select * from results where site_id = ? AND ref_code = ?", #site.id, utf8(result_params[:ref_code])]).first
if result.nil?
result_params[:site_id] = #site.id
result_params[:time_crawled] = DateTime.now().strftime "%Y-%m-%d %H:%M:%S"
result_params[:link] = url
result = Result.create result_params
else
result.result_fields.each do |f|
f.delete
end
result.link = url
result.time_crawled = DateTime.now().strftime "%Y-%m-%d %H:%M:%S"
result.html = result_params[:html]
fields = []
result_params[:result_fields_attributes].each do |f|
fields.push ResultField.new(f)
end
result.result_fields = fields
result.save
end
#rows_parsed +=1
msg = "Saved #{#rows_parsed}"
msg +=" of #{#rows_total}" if #rows_total.to_i > 0
log msg
return result
end
end
What's Wrong with this code?
Thanks

rails redirect after create problem

Could anyone help with this problem:
Upon "create", the user is redirected to the url: model/model_id (eg post/1), instead I am redirected to models/url_encoding_object (eg posts/.%23) and there is an "406 Not Acceptable" message in the console.
Typically, upon create, the console's message is "Processing PostsController#create (for 000.0.0.0 at 2009-11-23 12:32:52) [POST]", but with this error, the message is "Processing PostsController#create to # (for 000.0.0.0 at 2009-11-23 12:32:52) [POST]"
I've seen austinfromboston's response and tried his "old fashioned but effective" solution to that similar problem, but it doesn't work for me.
Any help would be greatly appreciated
Controller Code:
# POST /groups
# POST /groups.xml
def create
#group = Group.new(params[:group])
#group.category = params[:category]
#group.user = current_user
#here we add the current user to the membership collection of the group
#membership = #group.memberships.build(params[:membership])
#membership.group = #group
#membership.user = current_user
#membership.initiator = false
#membership.membership_status_id = 2
#and here we set the current_user as the owner of the group
#group_permission = #group.group_permissions.build(params[:group_permission])
#group_permission.membership = #membership
#group_permission.group_role = GroupRole.find_by_name('Owner')
unless params[:metro_area_id].blank?
#group.metro_area = MetroArea.find(params[:metro_area_id])
#group.state = (#group.metro_area && #group.metro_area.state) ?
#group.metro_area.state : nil
#group.country = #group.metro_area.country if (#group.metro_area &&
#group.metro_area.country)
else
#group.metro_area = #group.state = #group.country = nil
end
#group.tag_list = params[:tag_list] || ''
# unless #user.is_in_group?(#group)
# #user.memberships << #group
# end
respond_to do |format|
if #group.save
flash[:notice] = :group_was_successfully_created.l
format.html { redirect_to(group_path(#group.id)) }
else
format.html {
#metro_areas, #states = setup_metro_area_choices_for(#group)
if params[:metro_area_id]
#metro_area_id = params[:metro_area_id].to_i
#state_id = params[:state_id].to_i
#country_id = params[:country_id].to_i
end
render :action => "new"
}
end
end
end
Looks like either your routes are off somewhere or your model_id parameter is not what you are expecting. Might want to check to see what that parameter is being set to.
It's also really hard to give any suggestions without seeing controller code. Can you post the method making this call?
There's a lot of superfluous code, in your controller. It still works, but you're doing a lot of things the hard way.
Your problem is this line:
format.html { redirect_to(groups_path(#group.id)) }
Which redirects to the collective groups url adding the parameter #group.id.
What it should be is
format.html { redirect_to(group_path(#group.id)) }
# POST /groups
# POST /groups.xml
def create
#group = Group.new(params[:group])
#group.category = params[:category]
#group.user = current_user
#here we add the current user to the membership collection of the group
#membership = #group.memberships.build(params[:membership])
#membership.group = #group
#membership.user = current_user
#membership.initiator = false
#membership.membership_status_id = 2
#and here we set the current_user as the owner of the group
#group_permission = #group.group_permissions.build(params[:group_permission])
#group_permission.membership = #membership
#group_permission.group_role = GroupRole.find_by_name('Owner')
unless params[:metro_area_id].blank?
#group.metro_area = MetroArea.find(params[:metro_area_id])
#group.state = (#group.metro_area && #group.metro_area.state) ? #group.metro_area.state : nil
#group.country = #group.metro_area.country if (#group.metro_area && #group.metro_area.country)
else
#group.metro_area = #group.state = #group.country = nil
end
#group.tag_list = params[:tag_list] || ''
unless #user.is_in_group?(#group)
#user.memberships << #group
end
respond_to do |format|
if #group.save
flash[:notice] = :group_was_successfully_created.l
format.html { redirect_to(groups_path(#group.id)) }
else
format.html {
#metro_areas, #states = setup_metro_area_choices_for(#group)
if params[:metro_area_id]
#metro_area_id = params[:metro_area_id].to_i
#state_id = params[:state_id].to_i
#country_id = params[:country_id].to_i
end
render :action => "new"
}
end
end
end
What is this .1 doing at the end of the line??
flash[:notice] = :group_was_successfully_created.l
I tried to run similar code in my environment and it choked on that.
It should also reference:
group_path(id)
not
groups_path(id)

Resources