undefined method `i18n_key' for Address:Class - ruby-on-rails

I get this error when I load a page that contains a form (like edit.html.erb or new.html.erb). It freezes on the labels. I need to underline that I am not using ActiveRecord as an ORM in my app but Perpeuity gem which is an implementation of the Datamapper pattern. Leaving Activerecord behind has proved a bit problematic so maybe someone will be able to help.
The form partial:
<%= form_for(#address) do |f| %>
<% if #address.errors.to_a.any? %>
<div id="error_explanation">
<h2><%= pluralize(#address.errors.count, "error") %> prohibited this address from being saved:</h2>
<ul>
<% #address.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="row collapse">
<div class="small-3 columns">
<% require 'debugger'; debugger %>
<%= f.label :line1, class: "right inline" %>
</div>
<div class="small-7 columns left">
<%= f.text_field :line1 %>
</div>
</div>
<div class="row collapse">
<div class="small-3 columns">
<%= f.label :line2, class: "right inline" %>
</div>
<div class="small-7 columns left">
<%= f.text_field :line2, :placeholder => "(optional)" %>
</div>
</div>
<div class="row collapse">
<div class="small-3 columns">
<%= f.label :postcode, class: "right inline" %>
</div>
<div class="small-7 columns left">
<%= f.select :postcode, Address::POSTCODES, :prompt => 'Select a postcode (optional)' %>
</div>
</div>
<div class="row collapse">
<div class="small-3 columns">
<%= f.label :city, class: "right inline" %>
</div>
<div class="small-7 columns left">
<%= f.text_field :city %>
</div>
</div>
<div class="row collapse">
<div class="small-3 columns">
<%= f.label :county, class: "right inline" %>
</div>
<div class="small-7 columns left">
<%= f.select :postcode, Address::COUNTIES, :prompt => 'Select a county (optional)' %>
</div>
</div>
<div class="row collapse">
<div class="small-9 small-offset-3 columns">
<%= f.submit %>
</div>
</div>
The model:
class Address
extend ActiveModel::Naming
extend ActiveModel::Translation
include Perpetuity::RailsModel
def errors
#errors ||= ActiveModel::Errors.new(self)
end
def read_attribute_for_validation(attr)
send(attr)
end
def save
validate!
errors.empty? ? super : false
end
def validate!
#place custom validations here e.g.
errors.add(:name, "cannot be blank.") if self.name = ""
errors.add(:number,"must be less than 7.") if self.number >= 7
end
attr_accessor :name, :city, :county, :line1, :line2, :postcode
attr_reader :errors
end
The controller with relevant methods:
class AddressesController < ApplicationController
def new
#address = Address.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #address }
end
end
def edit
#require 'debugger'; debugger
#address = Perpetuity[Address].find(params[:id])
end
def create
#address = Address.new(params[:address])
Perpetuity[Address].insert #address
respond_to do |format|
if #address.save
format.html { redirect_to #address, notice: 'Address was successfully created.' }
format.json { render json: #address, status: :created, location: #address }
else
format.html { render action: "new" }
format.json { render json: #address.errors, status: :unprocessable_entity }
end
end
end
def update
#address = Perpetuity[Address].find(params[:id])
respond_to do |format|
if #address.update_attributes(params[:address])
format.html { redirect_to #address, notice: 'Address was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #address.errors, status: :unprocessable_entity }
end
end
end
end
I am using Rails 3.2 and ActiveModel gem installed has version 3.2.13. I had a look at the gem code and cannot find method i18n_key in it, while this documentation here [link]http://www.rubydoc.info/docs/rails/3.1.1/ActiveModel/Name:i18n_key indicates that it should be in there (similarly it is in 3.2.8 docs). Is it a bug or am I doing something wwrong? Thank your for your help.

I was getting this error and it turned out that I was using what appeared to be a reserved keyword in one of my classes. In my case it was model_name
Renaming it solved the issue for me.

Related

Uploading and getting Active Storage Blob before saving full record

Is it possible to set up a Rails form in a way that a user can upload images, and then be shown the direct link for their image before saving the rest of the form?
Use Case:
The use case is trying to be able to allow users to upload images, and then before saving the rest of the post, get links for those images and use the links in their markdown form in the same form.
I'm not familiar with Turbo, but maybe that's the way to go?
What I Have:
guide.rb
class Guide < ApplicationRecord
extend FriendlyId
friendly_id :title, use: :slugged
has_many_attached :images
acts_as_taggable_on :season, :tag
validates_presence_of :season_list, message: 'at least one season tag must be added'
validates_inclusion_of :season_list, in: %w[Spring Summer Fall Winter], message: '%<value>s is not a valid season'
end
guides_controller.rb
class GuidesController < ApplicationController
skip_before_action :verify_authenticity_token, only: %i[update_tags]
before_action :set_guide, only: %i[show edit update destroy]
rescue_from ActiveRecord::RecordNotFound, with: :guide_not_found
...
# GET /guides/new
def new
#guide = Guide.new
end
# GET /guides/1/edit
def edit; end
# POST /guides or /guides.json
def create
#guide = Guide.new(guide_params)
respond_to do |format|
if #guide.save
format.html { redirect_to guide_url(#guide), notice: 'Guide was successfully created.' }
format.json { render :show, status: :created, location: #guide }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #guide.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /guides/1 or /guides/1.json
def update
respond_to do |format|
if #guide.update(guide_params)
format.html { redirect_to guide_url(#guide), notice: 'Guide was successfully updated.' }
format.json { render :show, status: :ok, location: #guide }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #guide.errors, status: :unprocessable_entity }
end
end
end
...
private
# Only allow a list of trusted parameters through.
def guide_params
params.require(:guide).permit(:title, :body, :tag_list, :tags, season_list: [], images: [])
end
end
_form.html.erb
<%= form_with(model: guide, class: "contents", multipart: true) do |form| %>
<% if guide.errors.any? %>
<div id="error_explanation" class="bg-red-50 text-red-500 px-3 py-2 font-medium rounded-lg mt-3">
<h2><%= pluralize(guide.errors.count, "error") %> prohibited this guide from being saved:</h2>
<ul>
<% guide.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="my-5">
<%= form.label :title %>
<%= form.text_field :title, class: "block shadow rounded-md border border-gray-200 outline-none px-3 py-2 mt-2 w-full" %>
</div>
<div class="my-5">
<%= form.label :season %>
<% %w(Spring Summer Fall Winter).each do |season| %>
<%= form.check_box :season_list, { multiple: true }, season, nil %>
<%= label_tag season %>
<% end %>
</div>
<div class="my-10" data-controller="tagify">
<%= form.hidden_field :tag_list, value: #guide.tag_list.to_s, data: {"tagify-target": "hiddenField"} %>
<%= form.label :tags %>
<div >
<div data-tagify-target="input"></div>
</div>
</div>
<div class="py-10">
<%= form.label :image %>
<%= form.file_field :image, multiple: true, direct_upload: true, class: "block shadow rounded-md border border-gray-200 outline-none px-3 py-2 mt-2 w-full" %>
</div>
<div class="my-5">
<%= form.label :body %>
<%= form.text_area :body, rows: 4, class: "block shadow rounded-md border border-gray-200 outline-none px-3 py-2 mt-2 w-full" %>
</div>
<div class="inline">
<%= form.submit class: "rounded-lg py-3 px-5 bg-blue-600 text-white inline-block font-medium cursor-pointer" %>
</div>
<% end %>
Any help or direction to research is appreciated.

Ruby on Rails form error not giving any output/ not working

Hello guys I searched everywhere on how to output form errors but no luck. I tried almost all the code I found on the internet but still didn't work.
Here are some of my files:
view/books/new.html.erb
<div class="container">
<h2>Create a new book</h2>
<%= form_with model: #book, url: create_new_book_path do |f| %>
<% if #book.errors.any? %>
<ul>
<% #book.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>
<div class="form-group row">
<%= label_tag(:title, "Title:", class: "col-sm-2 col-form-label") %>
<div class="col-sm-10">
<%= f.text_field :title, class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= label_tag(:price, "Price:", class: "col-sm-2 col-form-label") %>
<div class="col-sm-10">
<%= f.text_field :price, class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= label_tag(:subject_id, "Subject:", class: "col-sm-2 col-form-label") %>
<div class="col-sm-10">
<%= f.collection_select :subject_id, #subjects, :id, :name, class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= label_tag(:description, "Book description:", class: "col-sm-2 col-form-label") %>
<div class="col-sm-10">
<%= f.text_area :description, class: "form-control" %>
</div>
</div>
<%= submit_tag "Create book", class: "btn btn-success" %>
<%= link_to "Cancel", books_path, class: "btn btn-danger" %>
<% end %>
<br/>
</div>
books_controller.rb
class BooksController < ApplicationController
def index
#books = Book.all
end
def show
#book = Book.find(params[:id])
end
def new
#book = Book.new
#subjects = Subject.all
end
def create
#book = Book.new(book_params)
end
def book_params
params.require(:book).permit(:title, :price, :subject_id, :description)
end
def edit
#book = Book.find(params[:id])
#subjects = Subject.all
end
def update
#book = Book.find(params[:id])
if #book.update_attributes(book_params)
redirect_to action: "index"
else
#subjects = Subject.all
render action: "edit"
end
end
def destroy
Book.find(params[:id]).destroy
redirect_to action: "index"
end
end
routes.rb
get 'books/new', to: 'books#new', as: 'new_book'
post 'books/create', to: 'books#create', as: 'create_new_book'
view/layouts/application.html.erb
<main role="main">
<%= yield %>
</main>
I don't really know what I'm missing to get the errors, grateful for your answers!!
try putting them in a flash like this and render it in your view
def create
#book = Book.new
if #book.update(book_params)
flash[:notice] = 'success'
redirect_to action: 'index'
else
flash[:alert] = #book.errors.full_messages.join(', ')
redirect_to action: 'index'
end
end
and in your view render those flashes like
<% if flash[:notice]%>
<span class='notice'><%= flash[:notice] %></span>
<% end %>
<% if flash[:alert]%>
<span class='alert'><%= flash[:alert] %></span>
<% end %>

AJAX not working in Rails same-page update

I am trying to build a Q&A app with Ajax on the Index.html.erb. I manage to get the form remotely loading, but when saving the records, the AJAX does not work and the user is taken to the normal show.html.erb. Apart from the Ajax not kicking off, everything works well.
My code is as below:
index.html.erb (Contain a partial for input, and a partial for results)
<div>
<h3 class="section_title"> Q&A </h3>
<hr>
<div id="qanda-form" style="display:none;"> </div>
</div>
<div id="qandas">
<%= render 'qandas/qanda' %>
</div>
_qanda.html.erb (is the partial for results)
<% #qandas.each do |my_qanda| %>
<div class="col-md-9">
<div>
Created <%= local_time(my_qanda.created_at) %>, by <%= User.find_by(id: my_qanda.user_id).full_name %>
</div>
</div>
<% end %>
_form.html.erb (is the input form - has nested form via Cocoon)
<%= simple_form_for #qanda, remote: true do |f| %>
<%= f.error_notification %>
<%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
<div class="col-md-12 form-inputs">
<div class="col-md-8">
<%= f.input :title, label: 'Q&A Title:' %>
</div>
</div>
<div class="qandasquestions">
<%= f.simple_fields_for :qandasquestions do |builder| %>
<% render 'qandas/qandasquestion_fields', f: builder %>
<% end %>
<div class="links btn-group" style="min-height: 34px !important">
<%= f.button :submit, "Publish Q&A", class: "btn btn-default" %>
<%= link_to_add_association 'Add Question', f, :qandasquestions, class: 'btn btn-default', data: {association_insertion_node: '.qandasquestions', association_insertion_method: :append} %>
<%= link_to 'Back', qandas_path, class: "btn btn-default" %>
<%= f.input :company, :as => :hidden, :input_html => {:value => current_user.company} %>
</div>
</div>
<% end %>
Controller:
def index
#qandas = Qanda.all
respond_to do |format|
#qandas = Qanda.all
format.html
format.json
end
end
def create
#qanda = current_user.qandas.build(qanda_params)
respond_to do |format|
if #qanda.save!
#qandas = Qanda.all
format.html { redirect_to #qanda, notice: 'Qanda was successfully created.' }
format.json {render :layout => false}
else
format.html { render :new }
format.json { render json: #qanda.errors, status: :unprocessable_entity }
end
end
end
create.js.erb
$('#qandas').html("<%= j render partial: 'qandas/qanda' %>");
$('#qanda-form').slideUp(350);
new.js.erb
$('#qanda-form').html("<%= j render 'qandas/form' %>");
$('#qanda-form').slideDown(350);
Anybody can see why the Ajax does not kick off please? why am I redirected to the traditional SHOW page please?
Try updating your code to this and let me know if it's working?
def create
#qanda = current_user.qandas.build(qanda_params)
if #qanda.save!
#qandas = Qanda.all
else
#errors = #qanda.errors
end
end

Validation errors are not displaying at multipart form in rails

I have a model BookingPost that has many Reservations.
In booking_posts/show.html.erb I have:
<div class="card-action">
<%= form_for([#reservation.booking_post, #reservation], html: {multipart: true}, class: "col s12") do |f| %>
<% if #reservation.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#reservation.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #reservation.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="col s6">
<%= f.label :start %>
<%= f.date_field :start, placeholder: "start time", class: "datepicker" %>
</div>
<div class="col s6">
<%= f.label :end %>
<%= f.date_field :end, placeholder: "end time", class: "datepicker" %>
</div>
<div class="col s6">
<%= f.label :reservation_time %>
<%= f.time_field :reservation_time, placeholder: "time", class: "timepicker", id: "timepicker", type: "time" %>
</div>
<div class="input-field col s6">
<%= f.label :name %>
<%= f.text_field :name, class: "validate" %>
</div>
<div class="input-field col s6">
<%= f.label :email %>
<%= f.text_field :email, class: "validate" %>
</div>
<div class="input-field col s6">
<%= f.label :phone_number %>
<%= f.text_field :phone_number, class: "validate" %>
</div>
<div class="waves-effect waves-light btn">
<%= f.submit t(:submit_reservation)%>
</div>
<% end %>
<br>
</div>
booking_posts_controller:
# GET /booking_posts/1
# GET /booking_posts/1.json
def show
#booking_picture = #booking_post.booking_pictures.build
#booking_pictures = #booking_post.booking_pictures
#reservation = #booking_post.reservations.build
#reservations = #booking_post.reservations
end
reservations_controller:
# GET /reservations/new
def new
#reservation = Reservation.new
end
def create
#booking_post = BookingPost.find(params[:booking_post_id])
#email= User.where(admin: true).first.email
#reservation = #booking_post.reservations.build(reservation_params)
respond_to do |format|
if #reservation.save
#saved_reservation = #reservation
format.html { redirect_to :back, notice: 'Reservation was successfully created.' }
format.json { render :show, status: :created, location: #reservation }
ReservationMailer.fresh_message(#saved_reservation, #email).deliver_now
else
format.html {redirect_to :back
flash[:info] = #reservation.errors.full_messages do |m|
m
end}
format.json { render json: #reservation.errors, status: :unprocessable_entity }
end
end
end
But I can't see any validation errors, even like presence: true.
Seems like I don't have correct #reservation, because I have a deal with Array in my form_for. Help me please to solve this issue, thanks!
The reason you are not seeing validation errors is because you are issuing a redirect_to :back when validations fails instead of rendering :new action which already includes any errors you might have inside the #reservation instance object.
Also you were trying to add the error messages into the flash message while trying to display them using the #reservation object.
this should be the correct else clause
else
format.html { render :new }
format.json { render json: #reservation.errors, status: :unprocessable_entity }
end

After submit form I want to stay in the same page and display :notice messages

All my code is working nicely, I want to render the same page :new after a user submits a form with your order. The problem is about the :notice message that I want to display Pedido enviado com sucesso. in the page after a submission but it doesn't work. My validation error messages are displayed nicely but I don't know why my success message doesn't.
Any tips?
(Sorry about my code indentation)
My pedidos_controller goes down:
class PedidosController < ApplicationController
def new
#pedido = Pedido.new
1.times do
pessoa = #pedido.build_pessoa
produto = #pedido.produtos.build
end
respond_to do |format|
format.html # new.html.erb
format.json { render json: #pedido }
end
end
def create
#pedido = Pedido.new(params[:pedido])
respond_to do |format|
if #pedido.save
PedidosMailer.delay.registro_do_pedido(#pedido)
PedidosMailer.delay.email_para_cotar_produtos(#pedido)
format.html { redirect_to action: "new", notice: 'Pedido enviado com sucesso.' }
format.json { render json: #pedido, status: :created, location: #pedido }
else
format.html { render action: "new" }
format.json { render json: #pedido.errors, status: :unprocessable_entity }
end
end
end
end
my new.html.erb view:
<p id="notice"><%= notice %></p>
<%= render 'form' %>
my _form.html.erb view:
<%= form_for(#pedido, :html => { :class => "form-contato"}) do |f| %>
<% if #pedido.errors.any? %>
<div id="error_explanation">
<h2>Ocorreram <%= pluralize(#pedido.errors.count, "erro") %></h2>
<ul>
<% #pedido.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="row">
<div class="span4">
<h1>Dados pessoais</h1>
<%= f.fields_for :pessoa do |builder| %>
<%= render 'pessoa_fields', f: builder %>
<% end %>
</div>
<div class="span8">
<h1>Ítens</h1>
<%= f.fields_for :produtos do |builder| %>
<%= render 'produto_fields', f: builder %>
<% end %>
</div>
<div class="span10">
<%= link_to_add_fields "Adicionar mais produtos", f, :produtos %>
</div>
<%= button_tag "Enviar", class: "btn btn-red span10", name: "commit" %>
</div>
<% end %>
my _pessoa_fields.html.erb view:
<fieldset>
<%= f.text_field :nome, class: "span4", placeholder: "Nome" %>
<br />
<%= f.text_field :telefone, class: "span4", placeholder: "Telefone" %>
<br />
<%= f.text_field :email, class: "span4", placeholder: "Email" %>
</fieldset>
my _produto_fields.html.erb view:
<% #lista_de_produtos = ["Qualibom standard", "Qualibom premium", "Bomdemais standard", "Bomdemais premium"] %>
<fieldset class="campos-produtos span10">
<div class="span3">
<%= f.select :nome, options_for_select(#lista_de_produtos, :selected => f.object.nome), :prompt => 'Selecione um produto' %>
</div>
<div class="span3">
<%= f.text_field :quantidade, class: "span3", placeholder: "Quantidade" %>
</div>
</fieldset>
You need to use flash[:notice], not notice, in your view:
<% if flash[:notice] %>
<p id="notice"><%= flash[:notice] %></p>
<% end %>
When you pass a message via the notice: parameter of redirect_to, it's placed into the flash array, which is a special pseduo-session which persist for a single request:
From the ActionController::Redirecting documentation:
It is also possible to assign a flash message as part of the redirection. There are two special accessors for the commonly used flash names alert and notice as well as a general purpose flash bucket.

Resources