Carrierwave can't save the image, using an engine - mysql

I'm learning to use Carrierwave the first step is obviously to upload a picture and see if it's effectively inserted to the database. One detail that could be important is that this code is written in a Rails Engine and namespaced (Wanker)
I generated an uploader following the instruction of the gem, everything went good (Wanker::PicturesUploader)
I made a model CompanyDetailImage with a picture string field (MySQL) and added this line
mount_uploader :picture, Wanker::PicturesUploader
Then I made a view and a form
<%= f.fields_for [:wanker, #company, #company_detail, #company_detail_images] %>
<%= i.label :picture %>
<%= i.file_field :picture %>
<% end %>
The params[:company][:company_detail_image]["picture"] in the controller will have this inside of it
[#<ActionDispatch::Http::UploadedFile:0x007fe613b81f40
#content_type="image/png",
#headers=
"Content-Disposition: form-data; name=\"company[company_detail_image][picture][]\"; filename=\"Screen Shot 2015-02-04 at 8.18.58 PM.png\"\r\nContent-Type: image/png\r\n",
#original_filename="Screen Shot 2015-02-04 at 8.18.58 PM.png",
#tempfile=# <File:/var/folders/2w/lw3glw5d58g25qvv4cx6yk0m0000gn/T/RackMultipart20150213-22947-np2et6>>]
Which for me seemed good. But when I try this
#company_detail_image = Wanker::CompanyDetailImage.new
#company_detail_image.picture = params[:company][:company_detail_image]["picture"]
#company_detail_image.save!
It returns this
ActiveRecord::RecordInvalid: Validation failed: Picture You are not allowed to upload nil files, allowed types: jpg, jpeg, gif, png
Does someone has an idea why it doesn't catch the picture ? Thank you guys ;)

Try this:
#company_detail_image.picture = params[:company][:company_detail_image]["picture"].first
This is because your ["picture"] param is returning an array rather than the object itself (which is the first item in that array).

Related

Linking to an API

I am trying to access a weather API that shows the icon of current weather.
My current code is:
response = HTTParty.get('http://api.openweathermap.org/data/2.5/weather?id=5911606&appid=734d8f2204043326b51df724c5c917f4', format: :json)
body = JSON.parse(response.body)["weather"][0]
#icon=body["icon"]
In html i am using the icon like:
<%= link_to image_tag('http://openweathermap.org/img/w/' + #icon +".png", :size => '130x130', :style => 'margin-top:45px;'), root_path%>
Its working fine when i first starts the server, but as I clicked any other link its gives me the following error:
nil is not a valid asset source
Does anybody know how to fix this?
it seems you are getting an empty #icon object. you can check for for empty icon object with #icon.blank? like following
<%= link_to image_tag('http://openweathermap.org/img/w/' + #icon +".png", :size => '130x130', :style => 'margin-top:45px;'), root_path unless #icon.blank? %>
if you can also think if having a helper method to display a default icon if the #icon is retuning a blank value
That means when you open any other links, I presume it calls a different actions where your code for #icon is not getting called and it is nil.
if you want #icon to be available for all the actions. You have to probably do it in a before action where you call the method populating #icon

Submitting an empty text field as an empty string, not null, in a multipart form

This is happening in my Rails app, but I'm not sure whether this is an issue with Rails or if I'm misunderstanding how multipart forms are supposed to work.
Here's (something like) my form:
<%= form_for #user do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
User#name has a presence validation. If I visit users/1/edit, empty out the value of the 'name' text field, and click submit, nothing gets updated because the presence validation fails. So far, so good.
But now I've added an avatar attribute to my User (using the Paperclip gem for file storage), so I update the form accordingly:
<%= form_for #user do |f| %>
<%= f.text_field :name %>
<%= f.file_field :avatar %>
<%= f.submit %>
<% end %>
Now, if I go to edit the user and submit a blank value for name, the validation doesn't fail. User#name keeps it previous value, but the update still appears to be successful (i.e. I don't get an error message about failed validations and the updated_at timestamp in the database gets updated.)
On closer inspection, it seems that when I include a file_field in the form, it changes the form's behaviour when submitting blank text fields (probably due to the fact that form_for now outputs a form with enctype=-"multipart/form-data").
When the file_field isn't present, submitting a blank name sends these params to the server:
{ "id" => 1, "user" => { "name: "" }
Which results in something like User.find(1).update_attributes(name: "") in the controller, which of course fails to update because Rails sees that we're trying to update 'name' to a blank string and the validation fails.
When it is present, this gets submitted:
{ "id" => 1, "user" => { } (plus extra info about the avatar file)
The "name" key isn't present at all, so the controller runs User.find(1).update_attributes() which of course passes as there's nothing being updated that might fail a validation.
Is this a bug, or a feature? Why would changing the enctype to multipart (assuming that's the source of the problem) change the way blank text fields behave? (I've tested this in both Chrome and FF, fwiw.) If this is really the intended behaviour, how can I ensure that blank text fields get submitted properly without having to add a bunch of tedious boilerplate around every text field?
(If it matters, I'm using: Ruby 2.3.0, Rails 5.0.0.beta3, Paperclip 5.0.0.beta1, and I've tested in Chrome 49 and Firefox 45)
I had the same issue, updating Rails to the latest version fixed it.
I think you can do something like that
updated_user = User.new(your_params) # The new attributes is set to a new object record
target_user = User.find(params[:id]) # the user you want to update
target_user = updated_user
if target_user.save?
..
else
..
by this all the validations will be triggered and the active record will have all the new attributes, if the name is blank it'll catch it
The following strong param method won't bring back the dropped :name parameter, but it should prevent the form from imitating a successful submit:
private
def user_params
params.require(:user).permit(:name, :avatar)
end
This can be inserted as a private method under your Users Controller. Then simply call user_params in your Update method.

Rails from a high-level view: performing calculations on a model value between view and controller

This must be a common need but I can't seem to find a definitive answer on the most rubyesque way. I need to create a fairly complex algorithm to dynamically calculate course grades in a rails 4.1 app.
Specifically, I have a model, "course", and whenever an instance of it is displayed in the view, I want to dynamically calculate the current grade (a decimal value, calculated from many course.field values) and display it as a letter value using a switch/case. My assumption was that I could do this in the controller (but it almost seems like it's complex enough to warrant it's own -- module? In C++ I would create a class). At the same time, since it is created dynamically, it seemed like bad form to create a current_grade field for it in the model, so it's not one I can pass back and forth as one of the allowable params (that I know of-- can one pass a variable in the params that is not represented in the db?).
In my initial research I see suggestions of hidden_field_tags and helper_methods and all_helpers and modules and global modules and more. Under time pressure, I dread beginning down the wrong path. Which is the better approach? Or a good high level doc for reference?
As an example, here is one view in which I would like to calculate current grade, compare it to desired grade, and display accordingly.
# index.html.erb
<% #courses.each do |course| %>
<li>
<%= my_algorithm_to_calculate_curr_grade(many course.fields used to caluculate)
<= course.desired_grade ? "set li to <Color: red>" : "set li to <Color: green>" %>
<%= course.course_name %>
Current Calculation: <%= display_results_of_previous_calculation %>
(Goal: <%= course.desired_grade %>)
<%= link_to 'Show', course %>
<%= link_to 'Edit', edit_course_path(course) %>
<%= link_to 'Drop Course Without Penalty', course, method: :delete, data: { confirm: 'Are you sure?' } %>
</li>
<% end %>
It's hard to tell from your question if course.fields are attributes of Course or different model(s). If all the fields are Course attributes, I would put it as an instance method on Course.
class Course < ActiveRecord::Base
def calculated_grade
# fun algorithm
end
end
If course.fields need to be loaded from the database, I'd probably go with a Plain Old Ruby Object (PORO), maybe call it CourseGradeCalculator (put it in app/models, why not? It's business logic)
class CourseGradeCalculator
attr_reader :course, :fields, :grade
def initialize(course, fields)
#course = course
#fields = fields
#grade = calculate_grade
end
private
def calculate_grade
# fun algorithm
end
end
# controller
#course = Course.preload(:fields).find(params[:id]
# view
CourseGradeCalculator.new(#course, #course.fields)

Rails 3 - find_all_by_car_id and nil object

I am getting this error:
[code]
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each
[/code]
In controller:
#optionals = Car.find_all_by_car_id(1)
In view:
<% #optionals.each do |c| %>
<div><%= c.type %></div>
<% end %>
In the table Car is one row... so I don't understand, how is possible to getting this error message... I tried to search on google, but unfortunately I still don't know how to fix this error...
So I'll glad for each help!
EDIT: car_id in table Cars have the value 1
Try adding a line in the template like so:
<%= #optionals.inspect %> and make sure it's not nil.
If it is, check the log to make sure the action that you're calling matches the template you're looking at

Rails validates_presence_of not working with HTML form text area

Environment: Rails 2.3.11 w/ MySQL 5.0
Here is my slideshow model:
class Slideshow < ActiveRecord::Base
validates_presence_of :title, :description
end
Using the console, if I run:
Slideshow.new(:title => "", :description => "").save!
it returns:
Validation failed: Title can't be blank, Description can't be blank
which is correct.
However, when I submit a blank HTML form to the create action:
def create
#slideshow = Slideshow.new(params[:slideshow])
if #slideshow.save
redirect_to(...)
else
render(:action => 'new')
end
end
only the :title field fails validation. I've verified that what is being passed in the params is:
Parameters: {"commit"=>"Submit", "slideshow"=>{"title"=>"", "description"=>""}, "action"=>"create", "controller"=>"manage/slideshows"}
Why is the description field NOT failing validation here?
Thanks.
Try this :
validates_length_of :description
for more details ... http://apidock.com/rails/ActiveRecord/Validations/ClassMethods/validates_length_of
when You submit a blank HTML form to the create action, it should go in else of create action and your form should have this line:
<%= f.error_messages %>
to show you the errors.
This turned out to be a syntax issue. It was occurring on a testing server where there were two models with very similar names (one an updated version of the other). During testing I used the wrong one. My apologies for any unnecessary head-scratching :)