I'm trying to implement this Angularjs upload in my rails application:
Angular File upload
This is my photos_controller:
def create
#photo = current_user.photos.new(photo_params)
respond_to do |format|
if #photo.save
format.html { redirect_to #photo, notice: 'Photo was successfully created.' }
format.json { render action: 'show', status: :created, location: #photo }
else
format.html { render action: 'new' }
format.json { render json: #photo.errors, status: :unprocessable_entity }
end
end
end
def photo_params
params.require(:photo).permit(:album_id, :user_id, :title, :description, :path)
end
I think that I'm close of the solution. When I try to upload I get this error:
param is missing or the value is empty: photo
Extracted source (around line #92):
9091929394
# Never trust parameters from the scary internet, only allow the white list through.
def photo_params
params.require(:photo).permit(:album_id, :user_id, :title, :description, :path)
end
end
I think that I need to format the data send to a format like this, isn't?
{"photo"=>{"tmpname"=>"253", "etc"=>"1"}}
The terminal log:
my html input:
<input type="file" nv-file-select="" name="photo[path]" id="photo_path" uploader="uploader" multiple /><br/>
My column with paper clip is path
I'm not getting how I do this in this angular script.
I don't have the rep to comment yet but usually this error comes from a naming issue, make sure your fields are named following the rails convention for example "photo[path]"
Related
I’m Rails beginner and I’m a bit overwhelmed by the quite simple problem. I would like to do something like this:
Users fills in a form.
Taps on the submit button
Model is saved into database.
If the save operation was successful, execute a javascript.
The questions is: how to accomplish that in the best way possible in Rails 6? Should I use .js.erb files? Or should I have javascript put into webpacker?
I tried so far the following code, but without any success:
controller/jobs_controller.rb
def create
#job = current_user.jobs.build(job_params)
respond_to do |format|
if #job.save
format.html { redirect_to #job, notice: 'Success!' }
format.js {}
else
format.html { render :new }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
views/jobs/create.js.erb
alert('hello');
As it was pointed out by #max-pleaner I was missing remote: true in the form tag.
I'm making a simple AJAX call from a from_tag (search box) and want to show the results without refreshing page. The issue is that even though I can see in server console that the show action is being processed as JS, it still renders the HTML and not the js.haml file. The only way I'm getting controller to render js is by changing name to show.js . It then works as it should. show.js.erb doesn't work either. I've also tried format.js {render layout: false} without any luck. It seem to be an problem on the controller side but I might be wrong here. Any ideas appreciated!
Edit:
The controller action is working using the render "show.js.haml" option. The other issue is that escape_javascript doesn't do anything in below js.haml file.
show.js.haml
$("#main").html("#{escape_javascript(render 'artists/show', locals: {artist: #artist, updates, #updates, reach: #reach, reach_diff: #reach_diff})}");
controller
class ArtistsController < ApplicationController
def index
if params[:search]
#artist=Artist.find_by(name: params[:search])
redirect_to action: "show", id: #artist.id
else
#artists= Artist.all
end
end
def show
#artist= Artist.find(params[:id])
#updates = #artist.updates.order(created_at: :desc)
#reach = #artist.reachupdates.order(created_at: :desc)
#reach_diff= Reachupdate.last_week_diff(#artist.id)
respond_to do |format|
format.html
format.js {render "show.js.haml", layout: false}
end
end
end
You need to change render layout: false to render 'show.js.haml', layout: false
def show
#artist= Artist.find(params[:id])
#updates = #artist.updates.order(created_at: :desc)
#reach = #artist.reachupdates.order(created_at: :desc)
#reach_diff= Reachupdate.last_week_diff(#artist.id)
respond_to do |format|
format.html
format.js {render 'show.js.haml', layout: false}
end
end
Update:
The next issue I'm having is to insert ruby objects to the js file
If the file 'articles/show' is a partial file then the problem is the locals keyword should be used along with partial keyword in order to work. Try changing this
$("#main").html("#{escape_javascript(render 'artists/show', locals: {artist: #artist, updates, #updates, reach: #reach, reach_diff: #reach_diff})}");
to
$("#main").html("#{escape_javascript(render partial: 'artists/show', locals: {artist: #artist, updates, #updates, reach: #reach, reach_diff: #reach_diff})}");
Or
Just remove locals
$("#main").html("#{escape_javascript(render 'artists/show', artist: #artist, updates, #updates, reach: #reach, reach_diff: #reach_diff)}");
I'm using the jQuery plugin Raty for my ruby on rails 4.0 application and it seems to be working except the images for the stars aren't loading onto the screen.
So those images should be stars ^ When I mouseover them in the console while running web brick the following is outputted. (My scaffold is called reviews)
Started GET "/reviews/star-off.png" for 127.0.0.1 at 2014-03-28 14:15:42 -0400
Processing by ReviewsController#show as PNG
Parameters: {"id"=>"star-off"}
Review Load (1.3ms) SELECT "reviews".* FROM "reviews" WHERE "reviews"."id" = $1 LIMIT 1 [["id", "star-off"]]
Completed 404 Not Found in 2ms
ActiveRecord::RecordNotFound (Couldn't find Review with id=star-off):
app/controllers/reviews_controller.rb:67:in `set_review'
I currently have the star images in apps/assets/javascripts/images but have also tried to put them in app/assets/images and app/views/reviews but they still won't show up. Is my issue that they aren't in the correct directory (and if so, which directory should they be in) or do I need to add some code manually to my reviews controller? Thanks.
edit: So when I try to use it in my index page, I only get an error saying this, so I must have to do something to my routes.rb file?
ActionController::RoutingError (NNo route matches [GET] "/star-off.png")
edit: as requested here is routes.rb
ConcertReview::Application.routes.draw do
resources :reviews
get "review/index"
get "review/artist"
get "review/date"
get "review/venue"
get "review/genre"
get "review/comments"
root 'reviews#index'
get 'reviews/' => 'reviews#index'
end
and here's reviews_controller.rb (autogenerated from scaffold and have not modified)
class ReviewsController < ApplicationController
before_action :set_review, only: [:show, :edit, :update, :destroy]
# GET /reviews
# GET /reviews.json
def index
#reviews = Review.all
end
# GET /reviews/1
# GET /reviews/1.json
def show
end
# GET /reviews/new
def new
#review = Review.new
end
# GET /reviews/1/edit
def edit
end
# POST /reviews
# POST /reviews.json
def create
#review = Review.new(review_params)
respond_to do |format|
if #review.save
format.html { redirect_to #review, notice: 'Review was successfully created.' }
format.json { render action: 'show', status: :created, location: #review }
else
format.html { render action: 'new' }
format.json { render json: #review.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /reviews/1
# PATCH/PUT /reviews/1.json
def update
respond_to do |format|
if #review.update(review_params)
format.html { redirect_to #review, notice: 'Review was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #review.errors, status: :unprocessable_entity }
end
end
end
# DELETE /reviews/1
# DELETE /reviews/1.json
def destroy
#review.destroy
respond_to do |format|
format.html { redirect_to reviews_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_review
#review = Review.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def review_params
params.require(:review).permit(:artist, :venue, :date, :genre, :sound, :stagePresence, :songSelection, :overallRating, :comments)
end
end
I had that very same problem on my project. The star images do belong in app/assets/images like you tried. However, you need to pass raty a path option like such:
$('div').raty({
readOnly: true,
halfScore: true,
score: 3,
path: '/assets'
});
This is working for me.
Also, if you have turbolinks on, you're going to have to tweek any $(document).ready(function () {...}); you might have. That was the problem I had right after this one.
In the "Working With Javascript" section of the Rails Edge Guides, an example is given of how to structure a 'create' action inside a 'User' controller, in order to integrate AJAX into the creation action:
# app/controllers/users_controller.rb
# ......
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.js {}
format.json { render json: #user, status: :created, location: #user }
else
format.html { render action: "new" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
I've read here that both 'format.js' and 'format.json' are needed, because Javascript and JSON are different types of response. My question is, if both formats are specified in the first half of the 'create' action's if statement, why aren't both also needed in the 2nd half? Does this mean that Javascript uses the 'create.js.erb' file on success, but not on failure?
Yes, you are correct. Based on skimming the guide, it looks like you don't want to do anything with js in the case of failure. If you were to put
format.js {}
in the failure block as well, then it would try to execute the render #user portion, which would probably cause an error anyway.
If you really did want to execute a js block in the event of failure, you could just do it the same way as for the other formats.
I have a strange problem. I have 2 models Issue, Comment. Comments is nested inside Issues so for that I have the create action in comments controller as follows:
def create
#issue = Issue.find(params[:issue_id])
#comment = #issue.comments.create!(params[:comment])
respond_to do |format|
if #comment.save
format.html { redirect_to #comment, notice: 'Comment was successfully created.' }
format.json { render json: #comment, status: :created, location: #comment }
format.js #create.js.erb
else
format.html { render action: "new" }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
And my create.js.erb:
var new_comment = $("<%= escape_javascript(render(:partial => #comment))%>").hide();
$('#comments').prepend(new_comment);
$('#comment_<%= #comment.id %>').fadeIn('slow');
$('#new_comment')[0].reset();
Issue.rb
class Issue < ActiveRecord::Base
attr_accessible :category, :description, :title
has_many :comments
end
Comment.rb
class Comment < ActiveRecord::Base
attr_accessible :body, :issue_id
belongs_to :issue
end
routes.rb
resources :comments
resources :issues do
resources :comments
end
Problem: When I create a comment for which is a form partial residing on views/issues/show.html.erb. The comment gets created 4 times in the db.
I couldn't locate what the problem was and whats causing it. Please help
First, I would build the associated comment:
#comment = #issue.comments.build(params[:comment])
And then I would save the comment instance
#comment.save
And also check the Javascript, maybe you are having some problems with event bubbling and the event is being triggered twice.
I actually was working on some old Rails version where the js files were put inside the /public/assets and that was the reason for that weird behaviour. I deleted all the files inside the /public/assets folder and the app works fine now.