undefined method `marked_for_destruction?' CarrierWave, RMagick - carrierwave

I am passing the ability to crop images, uploaded by Carrierwave. Here is RailsCast video on Youtube which I am following.
But after including RMagick in uploader, I received:
undefined method `marked_for_destruction?' for #<ImageUploader:0x007fe86634fcf0>
What a heck is this I thought. I haven't called this method anywhere. But if it is not defined, lets define it! And it worked! But later I checked more about this method and found that it is built in in Active Record Autosave Association module. And from docs, about this method:
Returns whether or not this record will be destroyed as part of the
parents save transaction.
Only useful if the :autosave option on the parent is enabled for this
associated model.
But I didn't passed autosave: true to any object!
So, my first question - was it done by default somehow?
2 - on RailsCast tutorial he didn't defined this method. Why I had to?
3 - I pass my code bellow. Any errors?
4 - if possible, could anyone explain how this process works, in general?
Many thanks!
product.rb:
has_one :image
validates :image, presence: true
mount_uploader :image, ImageUploader
products_controller.rb:
def create
#product = Product.new(product_params)
#product.category_id = params[:category_id]
#product.user_id = current_user.id
respond_to do |format|
if #product.save
if params[:product][:image].present?
format.html { render :crop }
else
format.html { redirect_to #product, notice: 'Product was successfully created.' }
format.json { render :show, status: :created, location: #product }
end
else
format.html { render :new }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
image_uploader.rb:
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
def marked_for_destruction?
#marked_for_destruction
end
def mark_for_destruction
#marked_for_destruction = true
end
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
version :large do
resize_to_limit(600,600)
end
end

If you're using Rails 5:
Open up new_framework_defaults.rb and change:
Rails.application.config.active_record.belongs_to_required_by_default = true
to
Rails.application.config.active_record.belongs_to_required_by_default = false
config.active_record.belongs_to_required_by_default is a boolean
value and controls whether a record fails validation if belongs_to
association is not present.

Inside your the *_uploader.rb file just write the function:
def marked_for_destruction?
end

Related

undefined method `name' for nil:NilClass on save

I'm posting here because i can't find anyone with this error. I'm using Rails 4.0.2 and when i try to save my form (it uses a collection_check_box) it gives me this message:
NoMethodError (undefined method `name' for nil:NilClass):
app/controllers/projeto_controller.rb:34:in `block in create'
app/controllers/projeto_controller.rb:33:in `create'
I'm a little lost here because i don't have any attributes named name.
Here my controllers and models.
class Projeto < ActiveRecord::Base
belongs_to :usuario
has_many :projeto_temas
has_many :temas, through: :projeto_temas
accepts_nested_attributes_for :temas
validates_presence_of :titulo, :orgao_financiador, :periodo_inicio, :periodo_fim
end
class ProjetoController < ApplicationController
# GET /projeto/new
def new
#projeto = Projeto.new
render :layout => 'application_cadastro'
end
# POST /projeto
# POST /projeto.json
def create
#projeto = Projeto.new(projeto_params)
respond_to do |format|
if #projeto.save
format.html { redirect_to #projeto, notice: 'Projeto was successfully created.' }
format.json { render action: 'show', status: :created, location: #projeto }
else
format.html { render action: 'new' }
format.json { render json: #projeto.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /projeto/1
# PATCH/PUT /projeto/1.json
def update
respond_to do |format|
if #projeto.update(projeto_params)
format.html { redirect_to #projeto, notice: 'Projeto was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #projeto.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_projeto
#projeto = Projeto.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def projeto_params
params.require(:projeto).permit(:titulo, :usuario_id, :orgao_financiador, :periodo_inicio, :periodo_fim, :resumo, :temas_ids => [])
end
end
And the Temas model.
class Temas < ActiveRecord::Base
has_many :relacionamento_temas_pai, class_name: RelacaoTemas, foreign_key: :temas_pai_id
belongs_to :relacionamento_temas_filho, class_name: RelacaoTemas, foreign_key: :temas_filho_id
has_and_belongs_to_many :projeto
accepts_nested_attributes_for :relacionamento_temas_pai
validates :nome, presence: true
end
The part of the view with the ckeck_box
<div class="presquisadores-preview-action">
<div class="temas-projetos-checkbox">
<%= f.collection_check_boxes :temas_ids, Temas.all, :id, :nome %>
</div>
</div>
It has one attribute with the name nome which is portuguese for name, so it shouldn't affect anything.
Thanks in advance for the help, in really lost, and don't know what to do.
--EDIT
So... after a lot of research i didn't find the problem. Actually i was looking into some rails documentation and saw some issues with that version of the activerecord so i updated to rails 4.2.0 and the problem is now gone.
I still don't know what caused it, but now my form saves normally.
Thanks for all the help folks
This is an issue with Rails 4.0.2. I faced the same issue and when I updated to Rails 4.0.13 (the last in the 4.0.x series), the issue resolved itself.
From the github issues, I can only glean that this is because of some database bugs that Rails did not prepare for.

Paperclip: "has an extension that does not match its content" error

I am just trying to do some really simple picture uploading using paperclip. I googled this issue and it seems like everyone else has much more complicated problem than simple uploads. Below are my models and controllers.
pin.rb
class Pin < ActiveRecord::Base
belongs_to :user
has_attached_file :image
validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
# validates the description
validates :description, presence: true
validates :user_id, presence: true
# validates paperclip
validates_attachment :image, presence: true,
content_type: { content_type: ["image/jpeg", "image/jpg", "image/png", "image/gif"]},
size: { less_than: 5.megabytes }
end
pin_controller.rb
class PinsController < ApplicationController
#before_filer will authentiate users to make sure they are logged in before doing anything with the Pins, with the except of indexing the pins so non-logged on users can also see them
before_filter :authenticate_user!, except: [:index]
before_action :set_pin, only: [:show, :edit, :update, :destroy]
# GET /pins
# GET /pins.json
def index
#pins = Pin.all
end
# GET /pins/1
# GET /pins/1.json
def show
end
# GET /pins/new
def new
# associate #pin to the current user's id
#pin = current_user.pins.new
end
# GET /pins/1/edit
def edit
# makes sure no other user can mess without a proper user id
#pin = current_user.pins.find(params[:id])
end
# POST /pins
# POST /pins.json
def create
# associate #pin to current user's id
#pin = current_user.pins.new(pin_params)
respond_to do |format|
if #pin.save
format.html { redirect_to #pin, notice: 'Pin was successfully created.' }
format.json { render action: 'show', status: :created, location: #pin }
else
format.html { render action: 'new' }
format.json { render json: #pin.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /pins/1
# PATCH/PUT /pins/1.json
def update
# makes sure no other user can mess without a proper user id
#pin = current_user.pins.find(params[:id])
respond_to do |format|
if #pin.update(pin_params)
format.html { redirect_to #pin, notice: 'Pin was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #pin.errors, status: :unprocessable_entity }
end
end
end
# DELETE /pins/1
# DELETE /pins/1.json
def destroy
# makes sure no other user can mess without a proper user id
#pin = current_user.pins.find(params[:id])
#pin.destroy
respond_to do |format|
format.html { redirect_to pins_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_pin
#pin = Pin.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def pin_params
params.require(:pin).permit(:description, :image)
end
end
Here are what I think might be wrong with my code.
First, I followed the One Month Rails Tutorial, but since I am watching the outdated Rails 3 series, I have to convert everything he teaches into Rails 4 by myself through research. I may have set up the strong parameters wrong in my pin.rb controller. I added :image attribute field to the pin_params method like so
params.require(:pin).permit(:description, :image)
is this the right way to add :image using strong parameters? In rails 3, he added :image within attr_accessible
Second, in the README for paperclip, it says I should run which convert and ultimately input this line in my config file
Paperclip.options[:command_path] = "/usr/local/bin/"
Since I am using a windows machine, this is what I got ultimately after looking answers for hours
Paperclip.options[:command_path] = "C:/Program Files/ImageMagick-6.8.9-Q16/"
does the above path looks relatively correct for windows?
I too use Windows and was getting this error. I found my answer here. From what I gather, Paperclip protects against spoofing by getting the server's OS to validate the file's MIME type. It does this by executing the following command:
file -b --mime <my_file_name.extension>
The trouble is, the standard Windows Command Line doesn't have the file command, so the spoofing check fails and Paperclip throws the error that you observed.
To resolve this issue:
Install File for Windows.
Edit your system's PATH variable so that it includes the "File for Windows" bin directory path. (For me, it was C:\Program Files (x86)\GnuWin32\bin.)
Restart your Command Line, Git Bash, or what have you because you edited your PATH variable.
Confirm that Windows Command Line now responds to the file command.
This method worked for me on Windows 8.1 with Paperclip 4.2.1.
In your pin.rb Delete this line
validates_attachment :image, presence: true,
content_type: { content_type: ["image/jpeg", "image/jpg", "image/png", "image/gif"]},
size: { less_than: 5.megabytes }
Because your already use
validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
I also do One More Rails with the outdated videos,like you.
Check for errors from my project
Here is the link My GigHub Project Files
Good Luck!)

Rails custom validate - uniqueness of a property across models

I'm stuck at defining a custom validation method that's purpose is to verify uniqueness of a property across two models
I realize this is bad code, but i wanted to get the test passing before refactor
here is a model with the custom validation to check another model property, error undefined local variable or method `params' (be gentle I'm still trying to figure out RoR)
class Widget < ActiveRecord::Base
include Slugable
validates :name, presence: true
validate :uniqueness_of_a_slug_across_models
def uniqueness_of_a_slug_across_models
#sprocket = Sprocket.where(slug: params[:widget_slug]).first
if #sprocket.present?
errors.add(:uniqueness_of_a_slug_across_models, "can't be shared slug")
end
end
end
You don't have access to params in a model. It belongs to controller and view. What you could do is to call custom method in widgets controller (instead of regular save) in order to pass params to a model:
class WidgetsController < ActionController::Base
def create
#widget = Widget.new(widget_params)
if #widget.save_with_slug_validation(params)
redirect_to widgets_path
else
render :new
end
end
end
and define it:
class Widget < ActiveRecord::Base
# ...
def save_with_slug_validation(params)
sprocket = Sprocket.find_by(slug: params[:widget_slug])
if sprocket
errors.add(:uniqueness_of_a_slug_across_models, "can't be shared slug")
end
save
end
end
I didn't test it but it should work.
P.S. Rails 4 style is used.
UPD
I should have tested it, sorry. Please use another approach.
Widgets controller:
# POST /widgets
# POST /widgets.json
def create
#widget = widget.new(widget_params)
#widget.has_sprocket! if Sprocket.find_by(slug: params[:widget_slug])
respond_to do |format|
if #widget.save
format.html { redirect_to [:admin, #widget], notice: 'widget was successfully created.' }
format.json { render action: 'show', status: :created, location: #widget }
else
format.html { render action: 'new' }
format.json { render json: #widget.errors, status: :unprocessable_entity }
end
end
end
Widget model:
class Widget < ActiveRecord::Base
include Slugable
validates :name, presence: true
validate :uniqueness_of_a_slug_across_models, if: 'has_sprocket?'
def uniqueness_of_a_slug_across_models
errors.add(:uniqueness_of_a_slug_across_models, "can't be shared slug")
end
def has_sprocket!
#has_sprocket = true
end
def has_sprocket?
!!#has_sprocket
end
end
It would be better to move has_sprocket! and has_sprocket? methods and maybe validation itself to Slugable concern.

Subform for parent object

So I've been holding off putting a question on here because I don't want to bother the community with stupid questions, but I'm going to ask for help now anyway.
I'm quite new to Ruby on Rails, and as you've probably read from the title, I'm having trouble with my subform. More specifically, with assigning the parent object to a client object. I'm building a system for my work in where employees can register repairs (mobile phones) and keep track of them. I'm building the client object with #repair = Repair.new, which works fine, but when I try to set the Client with #repair = Client.new, the :client_id on the repair stays null.
Here's my repair.rb: (some fields are in Dutch, please ignore that)
class Repair < ActiveRecord::Base
attr_accessible :imei, :klantnaam, :telefoon, :intake, :branch_id, :id, :client_id
attr_accessible :merk, :type, :batterij, :lader, :headset, :batterijklep, :carkit, :schade_toestel, :schade_scherm, :bon, :datum_bon, :klacht, :prijsindicatie
belongs_to :branch
belongs_to :client
accepts_nested_attributes_for :client
end
client.rb:
class Client < ActiveRecord::Base
attr_accessible :email, :firstname, :lastname, :number, :phone, :postalcode
has_many :repairs
end
repairs_controller.rb: (I've left the irrelevant methods out, I was getting tired of the 4 spaces :P)
class RepairsController < ApplicationController
# GET /repairs/new
# GET /repairs/new.json
def new
#repair = Repair.new
#repair.client = Client.new
if request.remote_ip == "xx.xx.xx.xx"
#repair.branch = Branch.where(:name => "Xxxxxxx").first
end
#repair.intake = Time.now
respond_to do |format|
format.html # new.html.erb
format.json { render json: #repair }
end
end
# POST /repairs
# POST /repairs.json
def create
#repair = Repair.new(params[:repair])
respond_to do |format|
if #repair.save
format.html { redirect_to #repair, notice: 'Repair was successfully created.' }
format.json { render json: #repair, status: :created, location: #repair }
else
format.html { render action: "new" }
format.json { render json: #repair.errors, status: :unprocessable_entity }
end
end
end
end
And this is the JSON I get from /repair/new.json:
{"batterij":null,"batterijklep":null,"bon":null,"branch_id":null,"carkit":null,"client_id":null,"created_at":null,"datum_bon":null,"headset":null,"id":null,"imei":null,"intake":"2013-02-01T23:29:10Z","klacht":null,"klantnaam":null,"lader":null,"merk":null,"pickup":null,"prijsindicatie":null,"schade_scherm":null,"schade_toestel":null,"telefoon":null,"updated_at":null}
By the way, the branch assignment works flawlessly... (It's null now because I'm not on the IP I specified in the new method)
Please help me out... :-(
Robin
Solved it!!
The code above all works flawlessly, the problem was a <% instead of <%= in my view, which made my subform not show up. Duhh.

Rails editing an Image attached to a model

I'm trying to set up a model (client) that contains some general attributes about a company but also has a company logo attached. I'm reluctant to use a plugin because I want to grasp this aspect of rails if possible.
I've created a clients model and an image model and I can create a new client (scaffold code) and upload an accompanying image ok (using has_one :image, and belongs_to :client).
I used the following code (taken straight from Agile Rails 3rd ed)
class Client < ActiveRecord::Base
has_one :image
def uploaded_image=(image_file)
self.image = Image.new
self.image.name = base_part_of(image_file.original_filename)
self.image.content_type = image_file.content_type
self.image.data = image_file.read
end
def base_part_of(filename)
File.basename(filename).gsub(/^\w_-/,'')
end
end
when editing the client object however, the new file is uploaded but the changes aren't reflected in the db. Do I need to explicitly call update-attributes on #client.image? At the moment my controller update method is as follows:
def update
#client = Client.find(params[:id])
respond_to do |format|
if #client.update_attributes(params[:client])
flash[:notice] = 'Client was successfully updated.'
format.html { redirect_to(#client) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #client.errors, :status => :unprocessable_entity }
end
end
end
Thanks in advance for any tips, apologies for the noob question
I would strongly recommend to use Paperclip instead. It just works.

Resources