Please reference this question: same question or another similar question
I cannot seem to get my work scaffold to include the image URL from paperclip to JSON. I need this url to do some ajax manipulation to the dom.
To my understanding you add a def in a model and then you add a extra line to the format.json in the controller.
when I add the #work.avatar_url to my controller method def create it throws up a syntax error
syntax error, unexpected ',', expecting tASSOC
I'm really new to rails and MVC. All the answers make it sound so easy. Unfortunately, I'm just guessing and checking...
Controller Link: works_controller.rb
My Def Create
def create
#work = Work.new(params[:work])
respond_to do |format|
if #work.save
format.html { redirect_to #work, notice: 'Work was successfully created.' }
format.json { render json: #work, status: :created, location: #work }
else
format.html { render action: "new" }
format.json { render json: #work.errors, status: :unprocessable_entity }
end
end
end
Git Link Model: work.rb
class Work < ActiveRecord::Base
validates :name, :presence => true
has_many :categoryworks
has_many :categories, :through => :categoryworks
accepts_nested_attributes_for :categories
attr_accessible :name, :subtitle, :category_ids, :svg, :post_a, :post_b, :post_c, :post_d, :avatar
has_attached_file :avatar, :styles => { :medium => "1280x700>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
def avatar_url
avatar.url(:medium)
end
end
Try
format.json { render json: #work.as_json(:methods => [:avatar_url]), status: :created, location: #work }
instead of what you have used.
Related
I am using Rails 5.001 and I want to test a controller-function from shared_list. Shared_list is nested under shopping_list.
shared_lists_controller_test.rb
class SharedListsControllerTest < ActionDispatch::IntegrationTest
include Devise::Test::IntegrationHelpers
include Warden::Test::Helpers
setup do
new_shopping_list = shopping_lists(:shopping_list_drogerie)
#heikoSharedList = shared_lists(:shared_list_heiko)
#heiko = users(:user_heiko)
end
test "should get edit" do
login_as(#heiko)
#heiko.confirmed_at = Time.now
get edit_shared_list_url(#heikoSharedList.shopping_list.id, #heikoSharedList)
assert_response :success
end
However when I run the test, I get this error message:
Error:
SharedListsControllerTest#test_should_get_edit:
ActiveRecord::RecordNotFound: Couldn't find SharedList with 'id'=102138810
test/controllers/shared_lists_controller_test.rb:49:in `block in <class:SharedListsControllerTest>'
Does somebody know what went wrong and how to fix this?
My fixtures look like this:
shared_lists
shared_list_heiko:
user: user_heiko
shopping_list: shopping_list_drogerie
created_at: <%= Time.now %>
updated_at: <%= Time.now %>
shopping_lists
shopping_list_drogerie:
user: user_heiko
name: Drogerie
created_at: <%= Time.now %>
updated_at: <%= Time.now %>
model/list_item.rb
class ListItem < ApplicationRecord
# db associations
belongs_to :shopping_list
has_many :shopping_items
# validations
validates :shopping_list, :presence => true
validates :name, presence: true, allow_blank: false
end
model/shopping_list.rb
class ShoppingList < ApplicationRecord
# db associations
belongs_to :user
# if a shopping list is deleted, also delete information about all items on the list
has_many :list_items, :dependent => :destroy
# if a shopping list is deleted, also delete information about who it was shared with
has_many :shared_lists , :dependent => :destroy
has_many :shared_with_users,through: :shared_lists, :source => :user
has_many :invitation
has_one :appointment
# validations
validates :user, :presence => true
validates :name, presence: true, allow_blank: false, uniqueness: {scope: :user_id}
end
controllers/shopping_lists_controller.rb
class ShoppingListsController < ApplicationController
load_and_authorize_resource
# GET /shopping_lists/1
# GET /shopping_lists/1.json
def show
end
# POST /shopping_lists
# POST /shopping_lists.json
def create
respond_to do |format|
if #shopping_list.save
format.html { redirect_to shopping_list_list_items_path(#shopping_list), alert: 'Shopping list was successfully created.' }
format.json { render :show, status: :created, location: #shopping_list }
else
format.html { render :new }
format.json { render json: #shopping_list.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /shopping_lists/1
# PATCH/PUT /shopping_lists/1.json
def update
respond_to do |format|
if #shopping_list.update(shopping_list_params)
format.html { redirect_to #shopping_list, notice: 'Shopping list was successfully updated.' }
format.json { render :show, status: :ok, location: #shopping_list }
else
format.html { render :edit }
format.json { render json: #shopping_list.errors, status: :unprocessable_entity }
end
end
end
# DELETE /shopping_lists/1
# DELETE /shopping_lists/1.json
def destroy
#shopping_list.destroy
respond_to do |format|
format.html { redirect_to shopping_lists_url, notice: 'Shopping list was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_shopping_list
#shopping_list = ShoppingList.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
private def shopping_list_params
params.require(:shopping_list).permit(:name)
end
end
I'm using active model serialiser.
I want to render both 'status' and 'data' in JSON format, e.g.
{"status":"success","data":[{"id":1,"content":xxx"}]}
I've been able to produce the 'data' using the following code in my rails controller:
#jobs = Job.all
render json: #jobs
How can I render both 'status' and 'data'? I've tried doing:
#jobs = Job.all
render :json => { :status => :success, :data => #jobs }
This doesn't recognize my JobSerializer, so renders JSON output, but not with the attributes and associations specified in my JobSerializer.
I've also tried:
#jobs = Job.all
render :json => { :status => :success, :data => ActiveModel::ArraySerializer.new(#jobs, each_serializer: JobSerializer) }
This appears to work, i.e. renders a JSON response with the right attributes speicified in my JobSerializer, but doesn't recognise or render the associations in my JobSerializer (i.e. a has_many association)
Is there an easy way to do this that I'm missing?
You can do something like:
render :json => {
status: "success",
data: ContentSerializer.new( contents ).attributes
}
Try this
#jobs = Job.all
render json: #jobs, status: 200
if above dosent work try this one
#jobs = Job.all
render json: #jobs, status: 200, serializer: JobSerializer
maybe you can try to render on this way:
#jobs = Job.all
render :json => { :status => :success, :data => #jobs.to_json }
UPDATE:
if you want to render and related objects, this should look like:
render :json => { :status => :success, :data => #jobs.to_json(:include => :users) }
here I assumed that the job model has users
Add attr_accessor to your model class
class Job < ApplicationRecord
attr_accessor :status
end
2.Then add same attribute to your serilizer
class JobSerializer < ActiveModel::Serializer
attributes :id, :name, :address, :email,:status
has_one :branch
end
3.Done add code like this in your controller
#job.status = 'success'
render json: #job, status: 200
#jobs = Job.all
render :json => { :status => :success, :data => (ActiveModel::ArraySerializer.new(#jobs, each_serializer: JobSerializer))
For has_many association to work, the association needs to be defined in both the model and serializer
class JobSerializer < ActiveModel::Serializer
has_many :association
end
class Section < ApplicationRecord
has_many :association
end
trying to setup a page so users can place an order when they sign in..
if you type in /listings/27/orders/new this will go to a new order form so you can order item 27. But when i fill in the address details and create an order I get error..NoMethodError in OrdersController#create..undefined method `order_url' for #
OrdersController#create
class OrdersController < ApplicationController
before_action :set_order, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
# GET /orders
# GET /orders.json
def index
#orders = Order.all
end
# GET /orders/1
# GET /orders/1.json
def show
end
# GET /orders/new
def new
#order = Order.new
#listing = Listing.find(params[:listing_id])
end
# GET /orders/1/edit
def edit
end
# POST /orders
# POST /orders.json
def create
#order = Order.new(order_params)
#listing = Listing.find(params[:listing_id])
#seller = #listing.user
#order.listing_id = #listing.id
#order.buyer_id = current_user.id
#order.seller_id = #seller.id
respond_to do |format|
if #order.save
# ERROR on the following line!!
format.html { redirect_to #order, notice: 'Order was successfully created.' }
format.json { render action: 'show', status: :created, location: #order }
else
format.html { render action: 'new' }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /orders/1
# PATCH/PUT /orders/1.json
def update
respond_to do |format|
if #order.update(order_params)
format.html { redirect_to #order, notice: 'Order was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
# DELETE /orders/1
# DELETE /orders/1.json
def destroy
#order.destroy
respond_to do |format|
format.html { redirect_to orders_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_order
#order = Order.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def order_params
params.require(:order).permit(:delivery_address, :delivery_city, :delivery_state)
end
end
listing.db
class Listing < ActiveRecord::Base
if Rails.env.development?
has_attached_file :image, :styles => { :medium => "200x", :thumb => "100x100>" }, :default_url => "photo.jpg"
else
has_attached_file :image, :styles => { :medium => "200x", :thumb => "100x100>" }, :default_url => "photo.jpg",
:storage => :dropbox,
:dropbox_credentials => Rails.root.join("config/dropbox.yml"),
:path => ":style/id_:filename"
end
validates :name, :description, :price, presence: true
validates :price, numericality: { greater_than: 0 }
validates_attachment_presence :image
belongs_to :user
has_many :orders
end
order.rb
class Order < ActiveRecord::Base
validates :delivery_address, :delivery_city, :delivery_state, presence: true
belongs_to :listing
belongs_to :buyer, class_name: "User"
belongs_to :seller, class_name: "User"
end
user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
validates :name, presence: true
has_many :listings, dependT.nt: :destroy
has_many :sales, class_name: "Order", foreign_key: "seller_id"
has_many :purchases, class_name: "Order", foreign_key: "buyer_id"
end
rake routes
devise_for :users
resources :listings do
resources :orders
end
get "pages/about"
get "pages/contact"
get 'seller' => "listings#seller"
root 'listings#index'
As per the nested routes,
devise_for :users
resources :listings do
resources :orders
end
order_url doesn't exist, redirecting to #order will make rails look for a path order_url.
Do rake routes and check the available paths(look at the prefix column).
Use
redirect_to listing_order_url(#listing,#order)
instead of
redirect_to #order
in both create and update actions of OrdersController.
Also, update destroy action as below
def destroy
#order.destroy
respond_to do |format|
format.html { redirect_to listing_orders_url(#order.listing) } ## orders_url doesn't exist, use listing_orders_url
format.json { head :no_content }
end
end
You are using nested resources. You should change the redirect to use a nested resource url, in this case to:
redirect_to listing_order_url(#listing, #order), notice: 'Your order has been created'
According to Rails Guides, if it's a link_to you could use this other format:
link_to 'Order Details', [#listing, #order]
I believe you're redirecting to a variable, while you should redirect to a URL present in you routes file.
I think it should be:
# ...
respond_to do |format|
if #order.save
format.html { listing_order_url(#listing, #order), notice: 'Order was successfully created.' }
format.json { render action: 'show', status: :created, location: #order }
else
format.html { render action: 'new' }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
I installed it by following the manual on paperclip github page and I get the given error. What am I doing wrong?
I have 4 input fields: title (text_field), description (text_area), price (text_field) and image (file_field). Why am I even getting this error with the prefix title in it? What has the title field got to do with it, are there any conflicts maybe? I did create and run the migrations so this is realy kind of weird I think.
Any help appreciated. Thanks.
EDIT:
The migration is as follows:
class AddImageColumnsToProducts < ActiveRecord::Migration
def change
add_attachment :products, :image
end
end
It results like so:
image_file_name varchar(255)
image_content_type varchar(255)
image_file_size int(11)
image_updated_at datetime
Model:
class Product < ActiveRecord::Base
has_attached_file :image, :styles => { :medium => "600x600>", :thumb => "258x258>" },
:default_url => "images/:style/:slug.png"
validates :title, :content, :image, :attachment_presence => true
validates_with AttachmentPresenceValidator, :attributes => :image
end
Controller:
def create
#product = Product.new(product_params)
#product.image = params[:product][:image]
respond_to do |format|
if #product.save
format.html { redirect_to #product, notice: 'Product was successfully created.' }
format.json { render action: 'show', status: :created, location: #product }
else
format.html { render action: 'new' }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
The issue is with your validation. The line which says
validates :title, :content, :image, :attachment_presence => true
assumes title, content & image as 3 image-based attributes. But, I understand that only 'image' is the image-based field. So, your code should rather be:
validates :title, :content, :presence=>true
validates :image, :attachment_presence => true
Also, I don't see the 'content' field in the request-log. I guess, you mean 'description'. Make sure you have the same attribute-names in the model-validations, database-schema & view files.
While applying logging concept to my book catalog display, when a user is regestering I am coming acorss this sort of error.
Can't mass-assign protected attributes: password_confirmation, password
And my code in app/model/user.rb is as follows:
class User < ActiveRecord::Base
attr_accessible :name, :password_digest
validates :name, :presence => true, :uniqueness => true
has_secure_password
end
And my code of create method in app/contollers/user_controller.rb
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
format.html { redirect_to users_url, :notice => 'User #{#user.name} was successfully created.' }
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
Any help please!
If you want to assign those values in the way you're doing it, you need to add them to the attr_accessible in your model:
attr_accessible :name, :password_digest, :password, :password_confirmation
I suspect you may not want to assign both of those, so you might want to delete them from that hash first (in the controller):
user = params[:user]
user.delete(:password_confirmation)
#user = User.new(user)
You could also create a new hash containing just the values you want to use to create the new User, if you have only a few values to keep but a lot of values to ignore.
(You could also create a new "empty" User and just assign the values you want - if that makes more sense in your situation.)