The problem occurs when I edit a post in my back-office. All the belong_to table don't save the informations were saved when I create the post.
I don't find solution on the web. I'm not an experiment dev so I don't now where I must look for.
My upload_file :
require "image_processing/mini_magick"
class ImageUploader < Shrine
plugin :processing # allows hooking into promoting
plugin :versions # enable Shrine to handle a hash of files
plugin :delete_raw # delete processed files after uploading
process(:store) do |io, context|
original = io.download
pipeline = ImageProcessing::MiniMagick.source(original)
size_200 = pipeline.resize_to_limit!(200, 200)
size_300 = pipeline.resize_to_limit!(300, 300)
original.close!
{ original: io, moyen: size_300, small: size_200 }
end
end
My model :
has_one :photo, as: :attachable
accepts_nested_attributes_for :photo
My controller :
# frozen_string_literal: true
class Admin::ActualitiesController < Admin::AdminController
before_action :set_actuality, only: %i[show edit update destroy]
def index
#actualities = Actuality.order('id DESC').page(params[:page]).per(10)
end
def new
#actuality = Actuality.new
#actuality.build_photo
end
def edit
end
def show; end
def create
#actuality = Actuality.new(actuality_params)
if #actuality.save
redirect_to :show, notice: ''
else
render :new, notice: ''
end
end
def update
if #actuality.update(actuality_params)
redirect_to :show, notice: ''
else
render :edit
end
end
def destroy
#actuality.destroy
redirect_to admin_actualities_path, notice: ''
end
private
def set_actuality
#actuality = Actuality.find_by(id: params[:id])
end
def actuality_params
params.require(:actuality).permit(:title, :body, :apercu, :meeting, photo_attributes: [:photo])
end
end
And in my form :
<%= f.simple_fields_for :photo do |ff| %>
<%= ff.input :photo, as: :hidden %>
<%= ff.input :photo, as: :file %>
<% end %>
If you have any solutions, I'm here !
Thanks !
Related
I've spent a while trying to debug this behavior unsuccessfully, so I'm hoping for help figuring out why my nested resource parameters appear to be getting included in the URL in the wrong order. For some reason, adding and deleting lessons for a course works, but editing a lesson crashes because ActiveRecord tries to find a lesson using the course ID and vice versa.
Course and lesson models
class Course < ApplicationRecord
has_many :lessons, dependent: :destroy
extend FriendlyId
friendly_id :title, use: :slugged
class Lesson < ApplicationRecord
belongs_to :course
extend FriendlyId
friendly_id :title, use: :slugged
Lessons controller
class LessonsController < ApplicationController
before_action :set_lesson, only: [:show, :edit, :update, :destroy ]
def index
#lessons = Lesson.all
end
def show
end
def new
#lesson = Lesson.new
#course = Course.friendly.find(params[:course_id])
authorize #lesson
end
def edit
authorize #lesson
end
def create
#lesson = Lesson.new(lesson_params)
#course = Course.friendly.find(params[:course_id])
#lesson.course_id = #course.id
if #lesson.save
redirect_to course_lesson_path(#course, #lesson), notice: "Lesson was successfully created."
else
render :new, status: :unprocessable_entity
end
end
def update
authorize #lesson
if #lesson.update(lesson_params)
redirect_to course_lesson_path(#course, #lesson), notice: "Lesson was successfully updated."
else
render :edit
end
end
def destroy
authorize #lesson
#lesson.destroy
redirect_to course_path(#course), notice: "Lesson was successfully destroyed."
end
private
def set_lesson
#course = Course.friendly.find(params[:course_id])
#lesson = Lesson.friendly.find(params[:id])
end
def lesson_params
params.require(:lesson).permit(:title, :content, :course_id)
end
end
Routes
resources :courses do
resources :lessons
end
And what shows up when I do rails routes:
edit_course_lesson GET /courses/:course_id/lessons/:id/edit(.:format)
However, when I actually edit a lesson, the parameters seem to get switched, which causes a crash. See below for an example of where it thinks the fourth lesson is the course.
URL: /courses/fourth-lesson/lessons/forensic-science-344/edit
ActiveRecord::RecordNotFound in LessonsController#edit
can't find record with friendly id: "fourth-lesson"
private
def set_lesson
#course = Course.friendly.find(params[:course_id]) <- Crashes on this line
#lesson = Lesson.friendly.find(params[:id])
end
Update: here's the form for editing a lesson.
.container
= simple_form_for([#course, #lesson]) do |f|
= f.error_notification
= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present?
.form-inputs
= f.input :title
= f.input :content
%small
= f.error :content, class: 'text-danger'
.form-actions
= f.button :submit, class: 'btn btn-primary my-4'
It turns out that I didn't pass in the course parameter on the edit link. I had link_to 'Edit', edit_course_lesson_path(lesson).
It should have been edit_course_lesson_path(#course, lesson).
Thanks for everyone's patience, and many thanks to Deepesh for finally getting it into my head to look at the edit link.
So I have these files
deal.rb
class Deal < ApplicationRecord
has_many :images, as: :imageable, dependent: :destroy
#there is more code after this
end
image.rb
class Image < ApplicationRecord
belongs_to :imageable, polymorphic: true
belongs_to :deal
has_attached_file :attachment, styles: { thumb: "100x100!", medium: "200x200!" }
validates_attachment_content_type :attachment, content_type: /\Aimage\/.*\z/
end
deals_controller.rb
module Admins
class DealsController < BaseController
before_action :find_deal, only: [:edit, :update, :destroy]
def index
#deals = Deal.includes(:images)
end
def new
#deal = Deal.new
end
def edit
end
def create
#deal = Deal.new(deal_params.merge(created_by: current_user.id))
if #deal.save
flash[:success] = t('.success')
redirect_to admins_deals_url
else
flash.now[:warning] = t('.failure')
render :new
end
end
def update
if #deal.update(deal_params)
flash[:success] = t('.success')
redirect_to admins_deals_url
else
flash.now[:warning] = #deal.errors[:base].to_sentence
render :edit
end
end
def destroy
if #deal.destroy
flash[:success] = t('.success')
redirect_to admins_deals_url
else
flash.now[:warning] = t('.failure')
render :index
end
end
private
def deal_params
params.require(:deal).permit(:title, :description, :price, :discounted_price, :quantity, :publish_date, images_attributes: [:id, :attachment, :_destroy])
end
def find_deal
#deal = Deal.find_by(id: params[:id])
unless #deal
flash[:warning] = t('deals.not_found')
redirect_to admins_deals_path
end
end
end
end
application_controller.rb
class ApplicationController < ActionController::Base
helper_method :current_user, :current_cart
def current_user
#current_user ||= User.find_by(id: current_user_id)
end
def current_user_id
cookies.signed[:user_id] || session[:user_id]
end
def current_cart
#current_cart ||= (current_user.addressed_cart || current_user.cart) if current_user
end
end
EDIT:
Although I don't think application_controller has anything to do with the error
I am creating a deal with nested image attributes. I am using paperclip to upload the images. But I am getting these errors. I don't have any idea what the errors even mean. Here is an image to show the errors.
Here is the pastebin link
errors on terminal on creating deal
This appears to be a validation error. Try this for your validation:
validates_attachment_content_type :attachment, :content_type => /image/
Or for other variations you can see Validate Attachment Content Type Paperclip
UPDATE after testing your code seems this was a validation error because Paperclip creates an image but doesn't know about the belongs_to association. You can make it optional because by default rails 5 requires the belongs_to id field.
class Image < ApplicationRecord
belongs_to :imageable, polymorphic: true
belongs_to :deal, optional: true
has_attached_file :attachment, styles: { thumb: "100x100!", medium: "200x200!" }
validates_attachment_content_type :attachment, content_type: /\Aimage\/.*\z/
end
I recently created a profile page for the users of the app am developing but along the way i noticed that the URL for the story originally is a little different from the same story on the users page. e.g normal url is "http://localhost:3000/genres/action/stories/37" while it is "http://localhost:3000/genres/absurdist/stories/37", meanwhile the story originally belongs to "action genre" and not "absurdist". Meanwhile, the two urls directs to the normal story page.
genre.rb
class Genre < ApplicationRecord
belongs_to :user
has_many :stories, dependent: :destroy
is_impressionable
extend FriendlyId
friendly_id :name, use: :slugged
def should_generate_new_friendly_id?
name_changed?
end
end
story.rb
class Story < ApplicationRecord
belongs_to :genre
belongs_to :user
has_many :episodes, dependent: :destroy
is_impressionable
extend FriendlyId
friendly_id :title, use: :slugged
def should_generate_new_friendly_id?
title_changed?
end
has_attached_file :image, size: { less_than: 1.megabyte }, styles: { medium: "300x300#", wide: "200x400#" }
validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/
scope :of_followed_users, -> (following_users) { where user_id: following_users }
end
profiles_controller
class ProfilesController < ApplicationController
before_action :find_user
before_action :find_genre
before_action :owned_profile, only: [:edit, :update]
before_action :authenticate_user!
def show
#stories = User.find_by(user_name: params[:user_name]).stories.order('created_at DESC')
impressionist(#user)
end
def edit
end
def update
if #user.update(profile_params)
flash[:success] = 'Your profile has been updated.'
redirect_to profile_path(#user.user_name)
else
#user.errors.full_messages
flash[:error] = #user.errors.full_messages
render :edit
end
end
private
def profile_params
params.require(:user).permit(:avatar, :bio)
end
def find_user
#user = User.find_by(user_name: params[:user_name])
end
def find_genre
#genre = Genre.friendly.find_by(params[:slug])
end
def owned_profile
#user = User.find_by(user_name: params[:user_name])
unless current_user == #user
flash[:alert] = "That profile does not belong to you"
redirect_to root_path
end
end
end
profiles show
<div class="container my-5">
<div class="card-columns clearfix">
<%= render #user.stories %>
</div>
</div>
My App allows a user to create an Event and people can RSVP to the event. The app worked well before adding the Friendly_id gem, it works well as far as creating a new Event, but the RSVPs do not work as when you click submit you get an error. Please look at my code and see if there is anything that I am missing. Thank you in advance.
Event Model
class Event < ApplicationRecord
extend FriendlyId
friendly_id :eventname, use: [:slugged, :finders]
belongs_to :user
def should_generate_new_friendly_id?
eventname_changed?
end
has_attached_file :image, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/:style/placeholder.png"
validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/
validates :eventname, presence: true
has_many :rsvps, dependent: :destroy
end'
Rsvp Model
class Rsvp < ApplicationRecord
extend FriendlyId
friendly_id :eventname, use: [:slugged, :finders]
belongs_to :event
end
Events Controller
class EventsController < ApplicationController
before_filter :authenticate_user!, except: [:show]
def index
#events = current_user.events.all
end
def show
#event = Event.friendly.find(params[:id])
end
def new
#event = current_user.events.build
end
def create
#event = current_user.events.build(event_params)
#event.user = current_user
respond_to do |format|
if #event.save
format.html { redirect_to #event, notice: "Successfully created" }
else
format.html { render "new" }
end
end
end
def edit
#event = Event.friendly.find(params[:id])
end
def update
#event = Event.friendly.find(params[:id])
if #event.update(event_params)
redirect_to #event
else
render 'edit'
end
end
def destroy
#event = Event.friendly.find(params[:id])
#event.destroy
redirect_to events_path
end
private
def event_params
params.require(:event).permit(:eventname, :date, :time, :venue, :description, :image)
end
end
Rsvp Controller
class RsvpsController < ApplicationController
def index
event = Event.friendly.find(params[:event_id])
#rsvps = event.rsvps
end
def new
event = Event.friendly.find(params[:event_id])
#rsvp = event.rsvps.friendly.build
respond_to do |format|
format.html
end
end
def create
event = Event.friendly.find(params[:event_id])
#rsvp = event.rsvps.build(rsvp_params)
respond_to do |format|
if #rsvp.save
format.html { redirect_to "/thanks" }
format.js
else
format.html { render :new }
format.js
end
end
end
def thanks
render params[:page]
end
private
def rsvp_params
params.require(:rsvp).permit(:status, :name, :message)
end
end
Routes
resources :events do
resources :rsvps
end
show event:
http://127.0.0.1:3000/events/birthday
create rsvp for event:
http://127.0.0.1:3000/events/3/rsvps/new
After submit error shows on:
http://127.0.0.1:3000/events/birthday/rsvps
Screenshot of Error I get
I managed to resolve this issue by updating the following:
class Rsvp < ApplicationRecord
belongs_to :event
end
changed this:
new_event_rsvp_path(event_id: #event.id)
to this:
new_event_rsvp_path(#event)
Creating new RSVP now shows in the Friendly_id way:
http://127.0.0.1:3000/events/birthday/rsvps/new
I've done this 10 times and every time I seem to run into some issue with nested forms. Here's what I have:
client controller:
def new
#client = Client.new
#contact = #client.contacts.new
#header = "New Client"
respond_to do |format|
format.html # new.html.erb
format.json { render json: #client }
end
end
client class:
class Client < ActiveRecord::Base
## ASSOCIATIONS ##
belongs_to :user
has_many :contacts, :dependent => :destroy
has_many :invoices
## ACCESSIBLE ##
attr_accessible :name, :address_line_one, :address_line_two,
:contacts_attributes
## NESTED ATTRIBUTES ##
accepts_nested_attributes_for :contacts
in the form:
= form_for(#client) do |f|
= f.fields_for(#contact) do |contact|
but i still get this error when submitting the form:
Can't mass-assign protected attributes: contact
and the params:
"client"=>{"name"=>"23",
"contact"=>{"name"=>"asdf",
"email"=>"af#gmail.com"}},
"commit"=>"Save"}
What I would do is:
def new
#client = Client.new
#client.contacts.build
#header = "New Client"
respond_to do |format|
format.html # new.html.erb
format.json { render json: #client }
end
end
And:
= form_for(#client) do |f|
= f.fields_for(:contacts) do |contact|