Encoding::UndefinedConversionError when trying to upload an image - file-upload

I am using the following code to upload the image in /public/uploads/ folder in my root rails directory.
uploaded_io = params[:product_image]
File.open(Rails.root.join('public','uploads', uploaded_io.original_filename), 'w') do |file|
file.write(uploaded_io.read)
end
My form looks like this
<%= form_tag({:action => :configure_product}, :multipart => true) do %>
<%= label_tag(:product_image, "Image:") %><br />
<%= file_field_tag 'product_image' %>
<%= submit_tag "Save and add another", :name => 'save and add another' %>
<%= submit_tag "Save", :name => 'save' %>
<% end %>
but when trying to submit the form I get the following error.
Encoding::UndefinedConversionError in ConfigureCategoryController#configure_product
"\xFF" from ASCII-8BIT to UTF-8
I replaced the writing mode from 'w' to 'wb' and now I am getting
NoMethodError in ConfigureCategoryController#configure_product
undefined method `name' for nil:NilClass
New at rails. Would surely appreciate the help.

You'll need to open the file as a binary file by appending b to the open type.
File.open("#{ Rails.root }/tmp/uploaded_image.gif", "wb") do |f|
The other issue you're having is specific to whatever it is your application does.

Related

Display error messages in rails simple_form

I am new to rails and was wondering if someone could show me some light...
I have a simple form with couple of input fields and need to display field validation messages below the field name. Is there is a straightforward way to say display errors below??? or do i have to check for each field error message and create a span tag?
You can specify in your simple_form.rb initializer file with which tag your error message will be wrapped:
b.use :error, :wrap_with => { :tag => :span, :class => :error }
Also you can disable default error component on the input and print it by yourself like this:
<%= simple_form_for #user do |f| %>
<%= f.input :name, error: false %>
<%= f.error :name %>
<%= f.submit %>
<% end %>
and style your error message like you want.

How to access one model within another model in Rails..?

I have one data model 'object' with fields->object_id, object_name.
That is: http://localhost:3000/objects/
I have created another model 'front_pages' (not created any migration in this, instead I have created some pages like 'search.html.erb'(by hand) and the associated controllers).
That is: http://localhost:3000/front_pages/
My question is: How to access/search the items stored in the 'object' database within the 'search.html.erb'.
"These two are in the same rails project folder"
-> How to display the search results into an HTML.erb file?
views/static_pages/show.html.erb
<% #npsobject.each do |npsobjects| %>
Nps:
Nps type:
Nps name:
|
Static_page Controller
class StaticPagesController < ApplicationController
def show
#npsobject=Npsobject.find(:all, :conditions => ['nps_name LIKE ?', "%#{params[ :search]}%"]);
end
views/static_pages/new.html.erb
<%= form_tag( { :action =>"show"}, { :method => "get"}) do %> # The action path is ok??
<%= text_field_tag :search, params[:search], :class => 'inputBox' %>
"button") %>
Please verify the above codes and guide me through, as Im new to RoR..:)
You need to move your
#npsobject = Npsobject.find
into show action
and then each it into your views/static_pages/show.html.erb
<% #npsobject.each do |nps| %>
<%= nps.nps_name %>
<% end %>

Ruby on Rails form_tag parameters missing

I have a form that takes date range value to generate a report with Jasper Reports
reports/statistic.html.erb
<%= form_tag("/reports/statistic", :method => "post", :target => "_blank") do %>
<%= label_tag(:from_date, "From Date:") %>
<%= text_field_tag :from_date %>
<%= label_tag(:to_date, "To Date:") %>
<%= text_field_tag :to_date %>
<br><br>
<%= submit_tag("Generate Report") %>
<% end %>
and this is reports_controller.rb
def statistic
#details=StatisticTable.where(:dateindb => (params[:from_date])..(params[:to_date])
send_doc(render_to_string(
:template => 'reports/statistic.xml', :layout => false), #source of xml and template
'/statistic/detail', #xml xpath2 query in reports
'statisticreport', #name of .jasper file
'StatisticReport', #name of pdf file
'pdf')
end
When I clicked Generate Report button, the report displays nicely in a pdf viewer in a new window. But when I try to save the pdf file, the pdf is empty and the date value is returned as null.
Also, I followed this tutorial http://oldwiki.rubyonrails.org/rails/pages/HowtoIntegrateJasperReports which explains where the send_doc method comes from.
I don't think the problem is in Jasper because if I replace this
#details=StatisticTable.where(:dateindb => (params[:from_date])..(params[:to_date])
with a pre-defined date value
#details=StatisticTable.where(:dateindb => ('2011-12-01')..('2011-12-31')
the report displays and saves perfectly. So I'm guessing there is something wrong with my Ruby on Rails variables setting?
Thanks!
I solved this by only changing form method to GET
<%= form_tag("/reports/statistic", :method => "get", :target => "_blank") do %>
<%= label_tag(:from_date, "From Date:") %>
<%= text_field_tag :from_date %>
<%= label_tag(:to_date, "To Date:") %>
<%= text_field_tag :to_date %>
<br><br>
<%= submit_tag("Generate Report") %>
<% end %>
and after report is generated in PDF, I clicked Save and the PDF saves the whole data perfectly.

2 render templates (from devise) on one page (rails 3)

I've installed devise for my rails app, i can go to the sign in page or the sign up page. But I want them both on a welcome page...
So I've made a welcome_page_controller.rb with the following function:
class WelcomePageController < ApplicationController
def index
render :template => '/devise/sessions/new'
render :template => '/devise/registration/new'
end
end
But when i go to the welcome page i get this error:
NameError in Welcome_page#index
Showing /Users/tboeree/Dropbox/rails_projects/rebasev4/app/views/devise/sessions/new.html.erb where line #5 raised:
undefined local variable or method `resource' for #<#<Class:0x104931c>:0x102749c>
Extracted source (around line #5):
2: <% #header_title = "Login" %>
3:
4:
5: <%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
6: <p><%= f.label :email %><br />
7: <%= f.email_field :email %></p>
8:
Does anybody knows a solution for this problem? Thanks in advance!
Does it have to do with the fact that it is missing the resource function? in the welcome_page controller? It's probably somewhere in the devise controller...?
Regards,
Thijs
Here's how I managed to did it.
I've put a sign up form in my home#index
My files:
view/home/index.html.erb
<%= render :file => 'registrations/new' %>
helper/home_helper.rb
module HomeHelper
def resource_name
:user
end
def resource
#resource = session[:subscription] || User.new
end
def devise_mapping
#devise_mapping ||= Devise.mappings[:user]
end
def devise_error_messages!
return "" if resource.errors.empty?
messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
sentence = I18n.t("errors.messages.not_saved",
:count => resource.errors.count,
:resource => resource_name)
html = <<-HTML
<div id="error_explanation">
<h2>#{sentence}</h2>
<ul>#{messages}</ul>
</div>
HTML
html.html_safe
end
end
You need that part because Devise works with something called resource and it should be defined so you can call your registration#new anywhere.
Like that, you should be able to register. However, I needed to display errors on the same page. Here's what I added:
layout/home.html.erb (the layout used by index view)
<% flash.each do |name, msg| %>
# New code (allow for flash elements to be arrays)
<% if msg.class == Array %>
<% msg.each do |message| %>
<%= content_tag :div, message, :id => "flash_#{name}" %>
<% end %>
<% else %>
# old code
<%= content_tag :div, msg, :id => "flash_#{name}" %>
<% end %> #don't forget the extra end
<% end %>
I found this code here
And here's something I created: I saved my resource object if invalid in a session so that the user hasn't to fill every field again. I guess a better solution exists but it works and it's enough for me ;)
controller/registration_controller.rb
def create
build_resource
if resource.save
if resource.active_for_authentication?
# We delete the session created by an incomplete subscription if it exists.
if !session[:subscription].nil?
session[:subscription] = nil
end
set_flash_message :notice, :signed_up if is_navigational_format?
sign_in(resource_name, resource)
respond_with resource, :location => redirect_location(resource_name, resource)
else
set_flash_message :notice, :inactive_signed_up, :reason => resource.inactive_message.to_s if is_navigational_format?
expire_session_data_after_sign_in!
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords(resource)
# Solution for displaying Devise errors on the homepage found on:
# https://stackoverflow.com/questions/4101641/rails-devise-handling-devise-error-messages
flash[:notice] = flash[:notice].to_a.concat resource.errors.full_messages
# We store the invalid object in session so the user hasn't to fill every fields again.
# The session is deleted if the subscription becomes valid.
session[:subscription] = resource
redirect_to root_path #Set the path you want here
end
end
I think I didn't forget any code. Feel free to use whatever you need.
Also, you can add your sign in form in the same page (something like that:)
<%= form_for("user", :url => user_session_path) do |f| %>
<%= f.text_field :email %>
<%= f.password_field :password %>
<%= f.submit 'Sign in' %>
<%= f.check_box :remember_me %>
<%= f.label :remember_me %>
<%= link_to "Forgot your password?", new_password_path('user') %>
<% end %>
Cheers !

Rails appends id to singular route when render edit after errors

I have the following singular route:
scope '/seller' do
resource :seller_profile, :path => "/profile", :only => [:show, :edit, :update]
end
and the following controller:
class SellerProfilesController < ApplicationController
before_filter :validate_user_as_seller
def show
#seller_profile = current_user.seller_profile
end
def edit
#seller_profile = current_user.seller_profile
end
def update
#seller_profile = current_user.seller_profile
if #seller_profile.update_attributes(params[:seller_profile])
redirect_to(seller_profile_path, :notice => 'Profile was successfully updated.')
else
render :action => "edit"
end
end
end
I use a singular route given that the user must be authenticated before gaining access to the controller and therefore I can get the seller_profile from the user logged in.
This works like a charm, with only one problem. When I edit the seller_profile and validation error happen, the form is edited again and the errors are displayed correctly. The problem is that rails appends to the url the id of the edited record. For instance,
when I first edit the record, the url is:
http://0.0.0.0:3000/seller/profile/edit
but if the form is submitted with validation errors, the form itself is redisplayed under
http://0.0.0.0:3000/seller/profile.2
where 2 is the ID of the record being edited.
The form is the following:
<%= simple_form_for #seller_profile do |f| %>
<%= f.input :name %>
<%= f.input :description %>
<%= f.submit %>
<% end %>
Everything, as said, works great but I would totally mask the ID in the url. What should I do?
I have not really worked too much with simple_form_for. But it looks like it is guessing your url always as if they were not single resources. You can provide a custom one:
<%= simple_form_for #seller_profile, :url => seller_profile_path do |f| %>
<%= f.input :name %>
<%= f.input :description %>
<%= f.submit %>
<% end %>