Upload images with TinyMCE and Rails 7 - ruby-on-rails

I m trying to upload an image with tinymce and rails 7 (active storage and tinymce-rails gem)
My controller image :
class UploaderController < ApplicationController
skip_forgery_protection
def image
blob = ActiveStorage::Blob.create_after_upload!(
io: params[:file],
filename: params[:file].original_filename,
content_type: params[:file].content_type
)
render json: {location: url_for(blob)}, content_type: "text / html"
end
end
My model controller (protected section) :
class Back::ThemesController < BackController
before_action :theme, only: [:edit, :update, :destroy]
def new
#theme = Theme.new
end
def create
#theme = Theme.new(theme_params)
if #theme.save
redirect_to admin_themes_path
else
render :new
end
end
My tinymce config :
toolbar:
  - file edit view insert format tools
plugins:
 - image
images_upload_url: '/uploader/image'
My routes :
post ‘uploader/image’, to: ‘uploader#image’
And in my form :
<%= tinymce %>
<%= f.input :description, as: :text, input_html: { class: "tinymce" , rows: 40, cols: 120 } %>
When I try to upload an image in my back office, tinymce return a wrong back url (http://localhost:3000/uploader/image ) and I get a routing error :
Started POST "/uploader/image" for ::1 at 2021-11-14 12:53:17 +0100
Processing by UploaderController#image as */*
Parameters: {"file"=>#<ActionDispatch::Http::UploadedFile:0x00007fd46f8d2b88 #tempfile=#<Tempfile:/var/folders/_r/ytzkgwbd15jfz9w_csgk1jn00000gn/T/RackMultipart20211114-53999-wsms1f.jpg>, #original_filename="80s.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"file\"; filename=\"80s.jpg\"\r\nContent-Type: image/jpeg\r\n">}
Completed 200 OK in 2ms (Views: 0.2ms | ActiveRecord: 0.0ms | Allocations: 892)
Started GET "/uploader/image" for ::1 at 2021-11-14 12:53:17 +0100
ActionController::RoutingError (No route matches [GET] "/uploader/image"):

Related

Error making duplicate get requests

I have a problem where my controller action is creating duplicate records. I have a search form that checks the database for a record, or if its not in the database, scrapes a website to create the record. This same action (not restful i know) is also creating a record of the search itself with a value of "success" or "failure" depending on if the record could be found. However, it is consistently duplicating the record of the search. Here is the form_tag:
<%= form_tag new_search_path, remote: true, method: :get, id: 'etf-lookup-form' do %>
...
<%= text_field_tag :etf, params[:etf], placeholder: "ETF ticker symbol EX: SPY", autofocus: true, class: 'form-control search-box input-lg', style: "text-transform: uppercase" %>
and the controller:
class SearchesController < ApplicationController
def new
if params[:etf]
#etf = Etf.find_by_ticker(params[:etf].upcase)
#etf ||= Scraper.new_from_lookup(params[:etf].upcase)
end
if #etf.present?
Search.create(ticker: params[:etf].upcase, user_id: current_user.id, status: "success" )
render :js => "window.location = '#{etf_path(#etf)}'"
else
Search.create(ticker: params[:etf].upcase, user_id: current_user.id, status: "failure" )
render :js => "window.location = '#{search_path}'"
end
end
The terminal output always shows the get request being made twice before rendering the new page. How can I solve this problem? And/or what is a better way to organize these controller actions? I also have an EtfsController which contains a show action. Here are a couple fragments of from the terminal:
Started GET "/search/new?utf8=%E2%9C%93&etf=spy&button=" for ::1 at 2017-05-01 20:05:49 -0400
Processing by SearchesController#new as JS
Parameters: {"utf8"=>"✓", "etf"=>"spy", "button"=>""}
.......
Completed 200 OK in 10ms (Views: 0.1ms | ActiveRecord: 2.0ms)
Started GET "/search/new?utf8=%E2%9C%93&etf=spy&button=" for ::1 at 2017-05-01 20:05:49 -0400
Processing by SearchesController#new as JS
...
Completed 200 OK in 9ms (Views: 0.1ms | ActiveRecord: 2.7ms)
Started GET "/etfs/1" for ::1 at 2017-05-01 20:05:49 -0400
Processing by EtfsController#show as HTML
...
Completed 200 OK in 126ms (Views: 117.9ms | ActiveRecord: 1.2ms)
Probably you can refactor your code to look like this and the problem should be gone:
before_action :set_etf, only: [:new]
after_action :create_search, only: [:new]
def new
render js: window_location
end
private
def create_search
Search.create(ticker: etf_params, user_id: current_user.id, status: "success" )
end
def etf_params
#etf_params ||= params[:etf].to_s.upcase
end
def set_etf
#etf = (Etf.find_by_ticker(etf_params) || Scraper.new_from_lookup(etf_params) if etf_params.present?
end
def window_location
return "window.location = '#{etf_path(#etf)}'" if #etf.present?
"window.location = '#{search_path}'"
end
This should do the trick, let me know how it goes!

Link to remote issue is not working correctly

Here is the live demo
I'm trying to show listbox using remote actions just searching params, but is not working.
Clients_controller.rb
def new
#client.new
end
def search_city
#cities = City.where('id= ?',params[:city_id])
respond_to do |format|
format.js
end
end
search_city.js.erb
$("#test").html("<%= escape_javascript(render(:partial => "city_results"))%>");
Models
Client.rb
belongs_to :city
City.rb
belongs_to :state
has_many :clients
State.rb
has_many :cities
Routes.rb
resources :clients do
match 'search_city',:via =>[:get], :on => :collection
end
_form.erb
<%= link_to "Get list cities", {:action => "search_city"}, :remote => true, :class => "button-link" %>
<div id = "test">Here this text will be replaced</div>
_city_results.erb
<%= select_tag "example",options_for_select(#cities.collect { |p| [p.name,p.id] }) %>
Here complete log:
Started GET "/clients/new" for 127.0.0.1 at 2016-04-14 17:31:03 -0500
Processing by ClientsController#new as HTML
Completed 200 OK in 133ms (Views: 107.4ms | ActiveRecord: 1.0ms)
Rendered client_management/clients/new.html.erb within layouts/application (21.6ms)
Started GET "/clients/search_city?city_id=1" for 127.0.0.1 at 2016-04-14 16:43:55 -0500
Processing by ClientManagement::ClientsController#search_city as JS
Parameters: {"city_id"=>"1"}
Province Load (0.2ms) SELECT `states`.* FROM `states` WHERE `states`.`city_id` = 1
Rendered clients/partials/_city_results.erb (1.9ms)
Rendered clients/search_city.js.erb (2.9ms)
Completed 200 OK in 7ms (Views: 4.7ms | ActiveRecord: 0.4ms)
INFO
SELECT `states`.* FROM `states` WHERE `states`.`city_id` = 1
RESULT: 1 (exist value)
PROBLEM:
Is not showing the select tag with options.
When I check if params are sended everything is ok but in the view is not replaced.
Need to install a gem?
Is just working with simple text without but need rails code.
I tried this:
$('#province').html("<%= escape_javascript( render :partial => 'clients/partials/city_results' ) %>");
$('#province').show();
def search city
....
respond_to do |format|
format.js
end
end

Rails paperclip uploading files to Amazon S3

I try to upload files to Amazon S3 with paperclip gem.
The connection to S3 works fine. in the logs there is mentiond that a connection has started. (No errors in log)
in rails console got this: Completed 200 OK in 16ms (Views: 14.2ms | ActiveRecord: 1.0ms)
But in database there is nothing. And there is no files on S3.
model:
class Movie < ActiveRecord::Base
# add File to Movie association on column mo
has_attached_file :movie
# validdates the file type
validates_attachment_content_type :movie, :content_type => /\Avideo\/.*\Z/
end
controller:
class MoviesController < ActionController::Base
# Method to add a new Movie
def addMovie
if request.post?
#movie = Movie.new(movies_params)
if #movie.save
redirect_to :addMovie
end
else
#movie = Movie.new
end
end
private
def movies_params
params.require(:movie).permit(:movietitle, :movieprice, :locked, :moviedescription, :currency, :language, :movie)
end
end
LOG
Parameters: {"utf8"=>"✓", "authenticity_token"=>"DELETED", "movie"=>{"movietitle"=>"sd", "movieprice"=>"1", "currency"=>"d", "language"=>"de", "locked"=>"0", "moviedescription"=>"adasdasd", "movie"=>#<ActionDispatch::Http::UploadedFile:0x00000003e14e68 #tempfile=#<Tempfile:/tmp/RackMultipart20151226-2017-u9g0ym.mp4>, #original_filename="2015-11-14 11.51.27.mp4", #content_type="video/mp4", #headers="Content-Disposition: form-data; name=\"movie[movie]\"; filename=\"2015-11-14 11.51.27.mp4\"\r\nContent-Type: video/mp4\r\n">}, "commit"=>"Save Movie"}

Ruby on Rails 4 Essential Training Error ActionController::ParameterMissing in SubjectsController#create

I'm working through Ruby on Rails 4 Essential Training from Lynda.com and I'm running in this error:
ActionController::ParameterMissing in SubjectsController#create
I basically have a form with 3 inputs, :name, :position, and :visible. I can enter the the information just fine but then I get the error when I hit the submit button. Here is the output from the server:
`Started POST "/subjects/create" for 127.0.0.1 at 2014-11-11 18:02:12 -0500
Processing by SubjectsController#create as HTML
Parameters: {"utf8"=>"√", "authenticity_token"=>"f6+AdWN3jWO6mL9jrPDgVGoAm/NTBF1GPxGasTaqMh0=", "subject"=>{"name"
=>"Default", "position"=>"5", "visible"=>"false"}, "commit"=>"Create Subject"}
(0.0ms) BEGIN
SQL (1.0ms) INSERT INTO `subjects` (`created_at`, `name`, `position`, `updated_at`) VALUES ('2014-11-11 23:02:12'
, 'Default', 5, '2014-11-11 23:02:12')
(4931.3ms) COMMIT
Redirected to http://localhost:3000/subjects/create?actions=index
Completed 302 Found in 4941ms (ActiveRecord: 4932.3ms)
Started GET "/subjects/create?actions=index" for 127.0.0.1 at 2014-11-11 18:02:17 -0500
Processing by SubjectsController#create as HTML
Parameters: {"actions"=>"index"}
Completed 400 Bad Request in 1ms
ActionController::ParameterMissing (param is missing or the value is empty: subject):
app/controllers/subjects_controller.rb:40:in `subject_params'
app/controllers/subjects_controller.rb:18:in `create'
SubjectsController
class SubjectsController < ApplicationController
layout false
def index
#subjects = Subject.sorted
end
def show
#subject = Subject.find(params[:id])
end
def new
#subject = Subject.new({:name => "Default"})
end
def create
#subject = Subject.new(subject_params)
if #subject.save
redirect_to(:actions => 'index')
# raise params.inspect
else
render('new')
end
end
def edit
end
def delete
end
private
def subject_params
# same as using "params[:subject]", except that it:
# - raises an error if :subject is not present
# - allows listed attributes to be mass-assigned
params.require(:subject).permit(:name, :position, :visible)
end
end
Looking at the server output it doesn't look like I'm passing the :visible attribute to the database even though the data shows up on the index page even after the error.
I don’t think :visible is the problem, looking at your logs, you are getting this error:
ActionController::ParameterMissing (param is missing or the value is empty: subject):
app/controllers/subjects_controller.rb:40:in `subject_params'
app/controllers/subjects_controller.rb:18:in `create'
This is because of this line:
Started GET "/subjects/create?actions=index" for 127.0.0.1 at 2014-11-11 18:02:17 -0500
Processing by SubjectsController#create as HTML
Parameters: {"actions"=>"index"}
Looks like you are redirecting to GET /subjects/create and passing in parameters actions=index, likely caused by this line in your controller:
redirect_to(:actions => 'index')
I think what you meant here was really :action (singular):
redirect_to(:action => 'index')
Regarding the issue with :visible not being saved, I can’t say much without knowing anything about the model, has visible been declared in the database schema?

Rails 4 API with Strong Parameters?

I'm building a simple API with Rails 4, but with my "create" method, it all goes horribly wrong.
Here is the relevant part of my routes file:
namespace :api, defaults: { format: 'json' } do
# /api/... Api::
scope module: :v1, constraints: ApiConstraints.new(version: 1, default: true) do
resources :users
end
end
Here is the api/v1/users_controller.rb:
class Api::V1::UsersController < ApplicationController
protect_from_forgery except: :create
respond_to :json
def index
respond_to do |format|
format.html {render text: "Your data was sucessfully loaded. Thanks"}
format.json { render text: User.last.to_json }
end
end
def show
respond_with User.find(params[:id])
end
def create
respond_with User.create(user_params)
end
def update
respond_with User.update(params[:id], params[:users])
end
def destroy
respond_with User.destroy(params[:id])
end
private
def user_params
params.require(:user).permit(:name, :age, :location, :genre_ids => [], :instrument_ids => [])
end
end
Whenever I try to add an API with JSON, I get "{"errors":{"name":["can't be blank"]}}"
It works to create a user with my regular controller, but I have a feeling my API controller is getting messed up because of the Strong Parameters.
Any suggestions for how to do this correctly in Rails 4?
Also, I have a few Has-Many-Through relationships through my user model. The API's user controller should be able to see that off the bat, right?
Thanks
EDIT:
I'm now getting this error:
EDIT:
{
"name": "Sally",
"age": "23",
"location": "Blue York",
"genre_ids": [1, 2, 3]
}
EDIT AGAIN
Even with adding the User parameter in my JSON call, it still gives me the same error of the :user param missing. Am I using strong parameters incorrectly? In my "regular" users_controller, I can create a user easily with a form that I have set up, but with this API controller, I can't seem to create one with JSON. Any other suggestions?
EDIT YET AGAIN
Here Is The Log From Start to Error
rails s
=> Booting WEBrick
=> Rails 4.0.1 application starting in development on http://0.0.0.0:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
[2013-12-19 14:03:01] INFO WEBrick 1.3.1
[2013-12-19 14:03:01] INFO ruby 1.9.3 (2013-02-22) [x86_64-darwin10.8.0]
[2013-12-19 14:03:01] INFO WEBrick::HTTPServer#start: pid=53778 port=3000
Started GET "/api/users" for 127.0.0.1 at 2013-12-19 14:03:02 -0500
ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
Processing by Api::V1::UsersController#index as JSON
User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT 1
Rendered text template (0.0ms)
Completed 200 OK in 142ms (Views: 27.8ms | ActiveRecord: 0.6ms)
[2013-12-19 14:03:03] WARN Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true
[2013-12-19 14:03:03] WARN Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true
Started POST "/api/users" for 127.0.0.1 at 2013-12-19 14:03:37 -0500
Processing by Api::V1::UsersController#create as JSON
Completed 400 Bad Request in 1ms
ActionController::ParameterMissing (param not found: user):
app/controllers/api/v1/users_controller.rb:40:in `user_params'
app/controllers/api/v1/users_controller.rb:20:in `create'
Rendered /usr/local/rvm/gems/ruby-1.9.3-p392/gems/actionpack- 4.0.1/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.7ms)
Rendered /usr/local/rvm/gems/ruby-1.9.3-p392/gems/actionpack-4.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.0ms)
Rendered /usr/local/rvm/gems/ruby-1.9.3-p392/gems/actionpack-4.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (0.8ms)
Rendered /usr/local/rvm/gems/ruby-1.9.3-p392/gems/actionpack- 4.0.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (31.6ms)
EDIT #6
Here is my "real" users_controller that lives in my app and not my API. The form creates a user from this controller and NOT the API controller.
class UsersController < ApplicationController
def index
#users = User.all
#genres = Genre.all
#instruments = Instrument.all
render json: #users
end
def new
#user = User.new
end
def show
#user = User.find(params[:id])
end
def create
#user = User.new(user_params)
if #user.save
render json: #user, status: :created, location: #user
else
render json: #user.errors, status: :unprocessable_entity
end
end
private
def user_params
params.require(:user).permit(:name, :age, :location, :genre_ids => [], :instrument_ids => [])
end
end
ALSO - The User Form
<div class="row">
<div class="span6 offset3">
<%= form_for(#user) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :age %>
<%= f.text_field :age %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :location %>
<%= f.text_field :location %>
<br>
<% Genre.all.each do |genre| %>
<%= check_box_tag "user[genre_ids][]", genre.id %>
<%= genre.name %><br>
<% end %>
<br>
<% Instrument.all.each do |instrument| %>
<%= check_box_tag "user[instrument_ids][]", instrument.id %>
<%= instrument.name %><br>
<% end %>
<%= f.submit "Create My Account!" %>
<% end %>
</div>
</div>
<%= users_path %>
Here is my user.rb File
class User < ActiveRecord::Base
validates :name, presence: true, length: { maximum: 50 }
has_many :generalizations
has_many :genres, through: :generalizations
has_many :instrumentations
has_many :instruments, through: :instrumentations
end
Here is what I have in my routes file:
namespace :api do
namespace :v1 do
resources :users
end
end
My POST Request
POST /api/v1/users HTTP/1.1
Host: localhost:3000
Cache-Control: no-cache
{ "user": { "name": "Sally", "age": "23", "location": "Blue York", "genre_ids": [1, 2, 3] } }
UPDATE
I changed my strong-params to be this:
def user_params
params.require(:user).permit(:name, :age, :location, :genre_ids => [], :instrument_ids => []) if params[:user]
end
So the "if" statement at the end makes the error go away, but whenever I post to my API, it gives me back "null". So this could be the same problem as before, but shown in a different way. But, at the same time, it could be progress!
Here Is The Log For The Previous Update
Started POST "/api/v1/users" for 127.0.0.1 at 2013-12-21 11:38:03 -0500
Processing by API::V1::UsersController#create as */*
(0.1ms) begin transaction
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
(0.1ms) rollback transaction
User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT 1
Rendered text template (0.0ms)
Completed 200 OK in 20ms (Views: 0.3ms | ActiveRecord: 0.6ms)
FINAL UPDATE
I was missing a few things, but the main thing that did it was that I was missing "Content-Type - application/json" as my Header.
I feel so accomplished! Thanks for all your help, everyone!
According to your code parameters in the JSON you are posting should be inside params[:user]. So the JSON should look like:
{
"user": {
"name": "Sally",
"age": "23",
"location": "Blue York",
"genre_ids": [1, 2, 3]
}
}
Rails 4 is a great choice for building APIs. I would go with the rails-api gem. It will perform way better than a full blown Rails stack.
I have built plenty of API's in Rails using the Rails API gem. Usually in combination with RABL (which you can use to create nice templates to render your JSON). I am not a big fan of integrating an API directly into your production Rails app (serving websites and JSON) as you will create a big mess over time when starting to add more versions to your API. There are some very good Railscasts (www.railscasts.com): Search for API.
When accessing your API you would use a global filter in your application_controller.rb file. You could do something like this:
before_filter :authenticate_user, :except => 'users#index'
private
def authenticate_user
#current_user = User.find_by_api_key(params[:token])
unless #current_user
render :status=>403, :json=>{:message=>"Invalid token"}
end
end
def current_user
#current_user
end
end
In this case you would send the token in your request (that's quick and dirty, rather use the header instead) as a request parameter. You need to add the API key or whatever you want to use to your user model. Just create a migration adding api_key or however you want to call it to the user model or create a new table with keys, secrets etc. and a user_id field for your belongs_to (and a User has_many api_keys, or has_one). This way you can allow your users at any time to change their keys etc. (re-generate) without messing with usernames/password or even allow them to have multiple API keys with some tags (testing, production, etc). For your user signup you could add to your model:
before_create :generate_api_key
and then create a simple method like:
def generate_api_key
begin
self.api_key = SecureRandom.hex
end while self.class.exists?(api_key: api_key)
end
Hope it helps!

Resources