Paperclip and nested attributes - not writing to the database - sqlite

I'm trying to upload multiple files on a form. I followed the rail casts for paperclip and nested attributes, and also this tutorial http://sleekd.com/general/adding-multiple-images-to-a-rails-model-with-paperclip/ but I can't seem to get it working...
I've also searched here in stack overflow, looked at all paperclip and nested attributes posts, but I can't seem to find my answer, it seems that I'm doing everything right...
What happens is that when I submit the form, it creates the ad (it's an ad app), it says everything is ok, but it doesn't write the image data to the database and also it doesn't upload the files...
So I have the Classified model:
class Classified < ActiveRecord::Base
has_many :classified_images, :dependent => :destroy
accepts_nested_attributes_for :classified_images, :reject_if => lambda { |t| t['classified_image'].blank? }
attr_accessible :classified_images_attributes, :access, :contact, :price, :bizType
end
Then, the Classified_Image model:
class ClassifiedImage < ActiveRecord::Base
belongs_to :classified
has_attached_file :photo, :styles => {:small => "150x150>", :large => "320x240>"},
:url => "/assets/products/:id/:style/:basename.:extension",
:path => ":rails_root/public/assets/classifieds/:id/:style/:basename.:extension"
validates_attachment_presence :photo
validates_attachment_size :photo, :less_than => 5.megabytes
attr_accessible :caption, :photo
end
On the Classified controller, on the "new" part, I have:
def new
#classified = Classified.new
3.times { #classified.classified_images.build }
respond_to do |format|
format.html # new.html.erb
format.json { render json: #classified }
end
end
On the "_form" I have:
<%= form_for #classified, :html => { :multipart => true } do |f| %>
...
<%= f.fields_for :classified_images do |builder| %>
<%= render 'image_fields', :f => builder %>
<% end %>
On the "image_fields" partial I have:
<% if f.object.new_record? %>
<li>
<%= f.label :caption %>
<%= f.text_field :caption %>
<%= f.label :photo %>
<%= f.file_field :photo %>
</li>
<% end %>
On the migration files I have:
class AddAttachmentPhotoToClassifiedImages < ActiveRecord::Migration
def self.up
add_attachment :caption, :classified_id, :photo
end
def self.down
drop_attached_file :caption, :classified_id, :photo
end
end
class CreateClassifiedImages < ActiveRecord::Migration
def change
create_table :classified_images do |t|
t.string :caption
t.integer :classified_id
t.timestamps
end
end
end
On the "development.rb" file I have:
Paperclip.options[:command_path] = "/usr/local/bin/"
Paperclip.options[:log] = true
Here's an example of the log when I commit the form:
Started POST "/classifieds" for 127.0.0.1 at 2013-05-19 23:39:43 +0100
Processing by ClassifiedsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"978KGJSUlmMEvr6Tysg5xYIEQzNLn5vod07g+Z7njkU=", "classified"=>{"contact"=>"918218338", "price"=>"1500", "access"=>"bons", "classified_images_attributes"=>{"0"=>{"caption"=>"teste", "photo"=>##original_filename="064_dont-count-the-days.jpg", #content_type="image/jpeg", >#headers="Content-Disposition: form-data; name=\"classified[classified_images_attributes][0][photo]\"; filename=\"064_dont-count-the-days.jpg\"\r\nContent-Type: image/jpeg\r\n", >#tempfile=#3954-11t04t>>}, "1"=>{"caption"=>""}, "2"=>{"caption"=>""}}}, "commit"=>"Criar novo >Classificado"}
(0.1ms) begin transaction
SQL (0.5ms) INSERT INTO "classifieds" ("access", "contact", "created_at", "price",) >VALUES (?, ?, ?, ?) [["access", "bons"], ["contact", "918218338"], ["created_at", Sun, 19 >May 2013 22:39:43 UTC +00:00], ["price", 1500], ["updated_at", Sun, 19 May 2013 22:39:43 UTC >+00:00]]
(0.8ms) commit transaction
Redirected to localhost:3000/classifieds/8
Completed 302 Found in 5ms (ActiveRecord: 1.4ms)
As you can see, it inserts into the "classifieds" table but not into the "classifieds_image" table, and also, I don't get any info from paperclip...
Sorry for all the code but this should be really something simple that i'm not seeing and as more information you've got, the better you can help me... Please let me know if you need any more code or info...

We spent days chasing a similar problem. In the end it was the :reject_if lambda for the accepts_nested_attributes_for call in the model that triggered in the wrong situations.
Now that I revisit the question, it seems that you have the same issue. Instead of:
:reject_if => lambda { |t| t['classified_image'].blank? }
you should probably have:
:reject_if => lambda { |t| t['photo'].blank? }
i.e. the name of the paperclip attribute instead of the nesting model.
It is a frustrating thing to get wrong since it fails silently, t['classified_image'] will be nil all the time and your attributes will be rejected as specified. :) At least we learned to be more careful with :reject_if...

Related

I get "unknown attribute 'password' for User." error while runing User.create on rails consol

I am trying to create User using
User.create ({email:"ayzabc66#gmail.com", password:"password",password_confirmation:"password"})
but I keep on getting below error:
/.rvm/gems/ruby-3.0.0/gems/activemodel-7.0.3/lib/active_model/attribute_assignment.rb:51:in `_assign_attribute': unknown attribute 'password' for User. (ActiveModel::UnknownAttributeError)
I have already uncommented gem "bcrypt", "~> 3.1.7" and ran bundle.
This is what my user.rb looks like:
class User < ApplicationRecord
#email :string
#password_digest:string
#password:string
#password_confirmation:string virtual
has_secure_password
end
And my db>migrate looks like:
class CreateUsers < ActiveRecord::Migration[7.0]
def change
create_table :users do |t|
t.string :email
t.string :password_digest
t.timestamps
end
end
end
If you run the following in Rails Console, do you get the list of attributes that you would expect?
=> User
If so, I would try uncommenting the lines that you have in your User model and see if that helps, so it would look like this:
class User < ApplicationRecord
email :string
password_digest:string
password:string
password_confirmation:string virtual
has_secure_password
end

has_and_belongs_to_many association in rails 4

I've done everything as in here http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association, but it doesn't work. I found some answers in stackoverflow, but still it doesn't work. I've made association for posters and types. But when I specify the type of the poster nothing happens. There is no adding to DB, and no types in the Poster's view. Here is my PostrsTypes creating table:
class PostersTypes < ActiveRecord::Migration
def change
create_table :posters_types, id: false do |t|
t.integer :poster_id
t.integer :type_id
end
add_index :posters_types, [:poster_id, :type_id]
end
end
Here is Poster model:
class Poster < ActiveRecord::Base
has_and_belongs_to_many :types
belongs_to :user
validates :title, :body, :publish_date, :user_id, :presence => true
end
And Type model:
class Type < ActiveRecord::Base
has_and_belongs_to_many :posters
validates :name, :presence => true
end
Any ideas why nothing is writing in the DB?
EDIT. That's my posters_controller, if you need it:
class PostersController < ApplicationController
before_action :set_poster, only: [:show, :edit, :update, :destroy]
before_filter :authenticate_user!, :except => :index
# GET /posters
# GET /posters.json
def index
#posters = Poster.all
end
# GET /posters/1
# GET /posters/1.json
def show
end
# GET /posters/new
def new
#poster = Poster.new
end
# GET /posters/1/edit
def edit
end
# POST /posters
# POST /posters.json
def create
#poster = Poster.new(poster_params)
#poster.user_id = current_user.id
respond_to do |format|
if #poster.save
format.html { redirect_to #poster, notice: 'Poster was successfully created.' }
format.json { render action: 'show', status: :created, location: #poster }
else
format.html { render action: 'new' }
format.json { render json: #poster.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posters/1
# PATCH/PUT /posters/1.json
def update
respond_to do |format|
if #poster.update(poster_params)
format.html { redirect_to #poster, notice: 'Poster was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #poster.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posters/1
# DELETE /posters/1.json
def destroy
#poster.destroy
respond_to do |format|
format.html { redirect_to posters_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_poster
#poster = Poster.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def poster_params
params.require(:poster).permit(:title, :body, :publish_date, :type_ids)
end
end
try using :type_ids=>[]
def poster_params
params.require(:poster).permit(:title, :body, :publish_date,:type_ids=>[])
end
This worked for me
So you've got your #poster now. After you call .save on it, it either saves, or it puts some errors in your model. Check your validations, and output them e.g. with #poster.errors (in your new-action, since this one is rendered if the save fails) and see what's wrong.

Can't send attributes through RailsAdmin custom action form

I am trying to set up a custom crop action with Rails Admin.
I have the action set up, but am having an issue passing the cropping coordinates to save the cropped image. I want to pass the 'crop_x', etc. attributes in the form, but for some reason they are not being passed. Perhaps my form is set up wrong?
Here is my form code:
= form_for #object, method: :put, :url => crop_path(:model_name => #abstract_model.to_param, :id => #object.id) do |f|
- %w[x y w h].each do |attribute|
= f.text_field "crop_#{attribute}", id: "crop_#{attribute}"
.form-actions
= f.submit 'Crop Image', class: 'btn btn-primary'
Here is my rails admin custom cropping action:
require 'rails_admin/config/actions'
require 'rails_admin/config/actions/base'
module RailsAdminCrop
end
module RailsAdmin
module Config
module Actions
class Crop < RailsAdmin::Config::Actions::Base
RailsAdmin::Config::Actions.register(self)
register_instance_option :member? do
true
end
register_instance_option :http_methods do
[:get, :put]
end
register_instance_option :visible? do
authorized? && (['Painting'].include? bindings[:abstract_model].model.to_s)
end
register_instance_option :bulkable? do
false
end
register_instance_option :pjax? do
true
end
register_instance_option :controller do
Proc.new do
if request.get? # show crop page
respond_to do |format|
format.html { render #action.template_name }
format.js { render #action.template_name, :layout => false }
end
elsif request.put? # Submit
Rails.logger.warn "\n=========================\n"
Rails.logger.warn #object.inspect
#object.image.recreate_versions!
flash[:notice] = "#{#object.title} successfully cropped."
redirect_to "/admin/#{#abstract_model.to_s.downcase}"
end
end
end
register_instance_option :link_icon do
'icon-th-large'
end
end
end
end
end
Here are my rails admin routes (they don't seem to add routes to any of my existing actions, so these are just the default routes):
Routes for RailsAdmin::Engine:
dashboard GET / rails_admin/main#dashboard
index GET|POST /:model_name(.:format) rails_admin/main#index
new GET|POST /:model_name/new(.:format) rails_admin/main#new
export GET|POST /:model_name/export(.:format) rails_admin/main#export
bulk_delete POST|DELETE /:model_name/bulk_delete(.:format) rails_admin/main#bulk_delete
history_index GET /:model_name/history(.:format) rails_admin/main#history_index
bulk_action POST /:model_name/bulk_action(.:format) rails_admin/main#bulk_action
show GET /:model_name/:id(.:format) rails_admin/main#show
edit GET|PUT /:model_name/:id/edit(.:format) rails_admin/main#edit
delete GET|DELETE /:model_name/:id/delete(.:format) rails_admin/main#delete
history_show GET /:model_name/:id/history(.:format) rails_admin/main#history_show
show_in_app GET /:model_name/:id/show_in_app(.:format) rails_admin/main#show_in_app

Disable JavaScript for a RSpecTest

I want to disable javascript for a rspec test.
Ex
it '[SP01/UC18/TC25] title error for 31 letters' do
#=> Disable javascript (because text box is already validated by JS to max input 30 characters)
fill_in('title', :with => 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')
#=> Enable javascript (because I want to track the error messages)
click_button 'submit'
page.should have_content 'error in title'
page.should have_content 'please enter less than 30 characters'
end
Here is the answer
describe '[SP01/UC25] title error for 31 letters', :js => false, :type => :request do
end

Model passes validation of :presence => true and still nil in database

user_type is a column in user model and it has to be :presence => true. It rejects in rspec when passing a nil to user_type. However the factory_girl can store a nil user_type into the field with sqlite3.
Running rails 3.1.0. rspec 2.6.0 and factory_girl 2.1.0
//user model:
validates :user_type, :presence => true
//Factory girl definition:
Factory.define :user do |user|
user.name "Test User"
user.email "test#test.com"
user.password "password1"
user.password_confirmation "password1"
user.status "active"
user.user_type "employee"
end
Factory.define :user_level do |level|
level.role "sales"
level.position "member"
level.team 1
level.association :user
end
//rspec case: passed
it "should reject user type nil" do
user = Factory.build(:user, :user_type => nil)
user.should_not be_valid
end
it "should take user type 'employee'" do
user = Factory.build(:user, :user_type => 'employee')
user.errors[:user_type].should be_empty
user.should be_valid
end
Any thoughts? thanks.
As Michael Hartl pointed out in his excellent Rails tutorial, Factory Girl bypasses attr_accessible in the model. For instance, you can overwrite the "magic" columns using Factory Girl. Perhaps this applies to validations as well?
It seems like it would be better in this case to actually create your user with User.new, since you are testing the process of creation and validation itself.

Resources