i get an error
undefined method `photo' for #<Post::ActiveRecord_Relation:0x00000004ad42e8>
my posts.index.html.erb
<%= image_tag #post.photo.url(:small) %>
gives me the above error and if i iterate
<% #post.each do |image| %>
<%= image_tag image.photo.url %>
<% end %>
i get this new error
SQLite3::SQLException: no such column: position: SELECT "posts".* FROM "posts" ORDER BY position ASC
here is my model, post.rb
Class Post < ActiveRecord::Base
require 'digest/md5'
has_attached_file :photo, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png",
:path => ":rails_root/public/assets/images/:id/:style/:basename.:extension"
validates_attachment_content_type :photo, :content_type => /\Aimage\/.*\Z/
validates_attachment_size :photo, :less_than => 5.megabytes
validates_attachment_content_type :photo, :content_type => ['image/jpeg', 'image/png']
include PublicActivity::Model
tracked
end
and my posts_controller.rb
class PostsController < ApplicationController
before_action :authenticate_user!
def index
##hotels = hotels.new()
#activities = PublicActivity::Activity.order("created_at desc")
#post = Post.order('position ASC')
respond_to do |format|
format.html # show.html.erb
format.json { render json: #picture }
end
end
def show
#post = Post.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #picture }
end
end
def new
#post = Post.new
respond_to do |format|
format.html # show.html.erb
format.json { render json: #picture }
end
end
def create
##post = Post.create( user_params )
#post = Post.new(params[:posts].permit(:hotels, :photo, :number, :price, :guest_house, :restaurant,:lodges, :description, :region))
if #post.save
redirect_to(:controller => 'homes',:action=> 'index')
else
render('new')
end
end
def edit
#post = Post.find(params[:id])
end
def update
#post = Post.find(params[:id])
#post = Post.update_attributes()
end
def delete
#post = Post.find(params[:id])
end
#def user_params
#params.require(:post).permit(:photo)
#end
end
i also have the public activity gem installed on my app and when i try to display the photos using
<%= link_to activity.trackable.photo %>
i get a link to where the photo was saved but not the actual image as shown below. help me out
Ah I finally realized my mistake. i used the link_to tag instead of the image_tag
Related
So I have two models : Artist and Artwork.
Artist have a :name parrameter
Artist have_many artworks and Artwork has_one Artist.
I don't understand why when I call for #artworks.artiste.name in the artworks Index I have this error :
undefined method `artist'
this is my index :
<div class="col-xs-12 col-md-6 col-xs-offset-0 col-md-offset-4 col-lg-offset-5">
<p id="notice"><%= notice %></p>
<h1><%= #artworks.artist.name %></h1>
<% #artworks.each do |artwork| %>
<div class="artwork-container">
<div class="artwork-info">
<span><%= artwork.title %></span>
<p><%= artwork.description %></p>
<span><%= artwork.price %></span>
<span><%= link_to 'Edit', edit_artist_artwork_path(:artist, artwork) %></span>
<span><%= link_to 'Destroy', artist_artwork_path(:artist, artwork), method: :delete, data: { confirm: 'Are you sure?' } %>
</span>
</div>
<div class="artwork-photo-container">
<div class="artwork-photo" style="background-image: url('<%= artwork.photo.url %>');"></div>
</div>
</div>
<% end %>
<br>
<%= link_to 'New Artwork', new_artist_artwork_path %>
</div>
this is my artwork controller :
class ArtworksController < ApplicationController
before_action :set_artwork, only: [:show, :edit, :update, :destroy]
# GET /artworks
# GET /artworks.json
def index
#artworks = Artwork.all
end
# GET /artworks/1
# GET /artworks/1.json
def show
#artwork = Artwork.find(params[:id])
end
# GET /artworks/new
def new
#artwork = Artwork.new
end
# GET /artworks/1/edit
def edit
end
# POST /artworks
# POST /artworks.json
def create
#artwork = Artwork.new(artwork_params)
respond_to do |format|
if #artwork.save
format.html { redirect_to artist_artwork_url(:artist, #artwork), notice: 'Artwork was successfully created.' }
format.json { render :show, status: :created, location: artist_artwork_url(:artist, #artwork) }
else
format.html { render :new }
format.json { render json: #artwork.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /artworks/1
# PATCH/PUT /artworks/1.json
def update
respond_to do |format|
if #artwork.update(artworks_params)
format.html { redirect_to artist_artworks_url(:artist, #artworks), notice: 'Artwork was successfully updated.' }
format.json { render :show, status: :ok, location: artist_artwork_url(:artist, #artworks) }
else
format.html { render :edit }
format.json { render json: #artwork.errors, status: :unprocessable_entity }
end
end
end
# DELETE /artworks/1
# DELETE /artworks/1.json
def destroy
#artwork.destroy
respond_to do |format|
format.html { redirect_to artist_artworks_url(:artist, #artworks), notice: 'Artwork was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_artwork
#artwork = Artwork.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def artwork_params
params.require(:artwork).permit(:title, :description, :ref, :dateof, :price, :stock, :front, :photo, artist_attributes: [ :name, :surname])
end
end
those are my 2 models:
class Artist < ActiveRecord::Base
has_many :artworks
end
class Artwork < ActiveRecord::Base
has_one :artist
accepts_nested_attributes_for :artist
has_attached_file :photo, default_url: "/images/:style/missing.png"
validates_attachment_content_type :photo, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
validates_attachment_presence :photo
validates_presence_of :title, :description, :stock, :front, :price
end
Change has_one :artist to belongs_to :artist. The reason is that has_one doesn't store an id, so the two models don't really have any association. belongs_to adds an artist_id field.
Ok so I solved the error by replacing <h1><%= #artworks.artist.name %></h1>
by <%= #artworks.first.artist %>
Thanks you
I'm creating a new Purchase from the create method of the ChargesContoller.
I can successfully create the new Purchase and pass the information related to the charge.
My questions is: How can I get the order id to the Purchase?
Here' how the checkout process works:
Event > Option > Reservation > Order "has many reservations" >
in the Order show view, I have the Stripe button which creates a new charge > redirect to Purchase.
The Purchase is basically a receipt for the order. That's why I would like to show the order id and the reservations associated with the order. I know is not passing the order id because I can see it in the rails console
Should I use a different kind of association like has_many_and_belongs_to_many?
Maybe a joinTable?
I was reading at this part of the rails guides but I'm not sure if I'm looking in the right place: http://guides.rubyonrails.org/association_basics.html
or maybe is the way I'm trying to pass the order id "in the charges create" to the purchase:
purchase = Purchase.create(customer_email: params[:stripeEmail], amount: params[:amount],
customer_card: params[:stripeToken], order_id: params[:order_id], customer_id: customer.id)
Order Model:
class Order < ActiveRecord::Base
belongs_to :order_status
belongs_to :purchase
has_many :reservations
before_create :set_order_status
before_create :create_unique_identifier
before_save :total_for_no_price
before_save :update_subtotal
def to_param
uuid
end
def subtotal
reservations.collect{ |r| r.price }.sum
end
def total_for_no_price
if self.subtotal.nil?
self[:subtotal] = 0
end
end
def create_unique_identifier
self.uuid = SecureRandom.uuid
end
private
def set_order_status
self.order_status_id = 1
end
def update_subtotal
self[:subtotal] = subtotal
end
end
Purchase model:
class Purchase < ActiveRecord::Base
has_many :orders
has_many :reservations, through: :orders
end
Charges Controller:
class ChargesController < ApplicationController
def new
end
def create
# Amount in cents
#order = Order.find_by_uuid(session[:order_id])
#reservations = #order.reservations
#amount = #order.subtotal.to_i * 100
customer = Stripe::Customer.create(
:email => params[:stripeEmail],
:source => params[:stripeToken]
)
charge = Stripe::Charge.create(
:customer => customer.id,
:amount => #amount,
:description => #order.id,
:currency => 'usd'
)
purchase = Purchase.create(customer_email: params[:stripeEmail], amount: params[:amount],
customer_card: params[:stripeToken], order_id: params[:order_id], customer_id: customer.id)
if charge.save
#order_id = #order.update_attributes(order_status_id: 2)
#redirect_to #order
redirect_to purchase
reset_session
end
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to new_charge_path
end
end
Orders Controller:
class OrdersController < ApplicationController
before_action :set_order, only: [:show, :edit, :update, :destroy]
# GET /orders
# GET /orders.json
def index
#orders = Order.all
end
# GET /orders/1
# GET /orders/1.json
def show
#order = Order.find_by_uuid(params[:id])
#reservations = #order.reservations
end
# GET /orders/new
def new
#order = Order.new
end
# GET /orders/1/edit
def edit
end
# POST /orders
# POST /orders.json
def create
#order = Order.new(order_params)
respond_to do |format|
if #order.save
format.html { redirect_to #order, notice: 'Order was successfully created.' }
format.json { render :show, status: :created, location: #order }
else
format.html { render :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 { render :show, status: :ok, location: #order }
else
format.html { render :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, notice: 'Order was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_order
#order = Order.find_by_uuid(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def order_params
params.require(:order).permit(:subtotal, :tax, :total, :order_status_id, :uuid)
end
end
Order Show page with the charge button:
<div class="container-fluid events-container">
<div class="row">
<div class="col-sm-12">
<h4>Your Registrations:</h4>
<% #order.reservations.each do |reservation| %>
<h4><%= reservation.name %> <%= reservation.lastname %> | <%= reservation.email %> | <%= reservation.phone %></h4>
<h4><%= reservation.gender %> <%= reservation.shirt %> </h4>
<% unless reservation.team === 'N/A' %>
<h4>Team: <%= reservation.team %></h4>
<% end %>
<% unless reservation.redeemcode === 'N/A' %>
<h4>Redeem Code: <%= reservation.redeemcode %></h4>
<% end %>
<hr>
<% end %>
<h1>Order Total: <%= number_to_currency(#order.subtotal)%></h1>
<% if #order.order_status_id === 1 %>
<%= form_tag charges_path(#order) do %>
<article>
<% if flash[:error].present? %>
<div id="error_explanation">
<p><%= flash[:error] %></p>
</div>
<% end %>
</article>
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="<%= Rails.configuration.stripe[:publishable_key] %>"
data-description= "Event Registration(s)"
data-amount="<%= #order.subtotal.to_i * 100%>"
data-locale="auto">
</script>
<% end %>
<% end %>
<h3>Need to Modify you order? <%= link_to 'Back to Cart', cart_path %> </h3>
</div>
</div>
</div>
I solve this by changing:
order_id: params[:order_id] to order_id: (#order.id)
in the Charges Controller
Updated Charges Controller:
class ChargesController < ApplicationController
def new
end
def create
# Amount in cents
#order = Order.find_by_uuid(session[:order_id])
#reservations = #order.reservations
#amount = #order.subtotal.to_i * 100
customer = Stripe::Customer.create(
:email => params[:stripeEmail],
:source => params[:stripeToken]
)
charge = Stripe::Charge.create(
:customer => customer.id,
:amount => #amount,
:description => #order.id,
:currency => 'usd'
)
purchase = Purchase.create(customer_email: params[:stripeEmail], amount: params[:amount],
customer_card: params[:stripeToken], order_id: (#order.id), customer_id: customer.id)
if charge.save
#order_id = #order.update_attributes(order_status_id: 2)
#redirect_to #order
redirect_to purchase
reset_session
end
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to new_charge_path
end
end
I am trying to create a page within my application that shows all listings from a specific user. I am using Devise gem for my users. i do not need/want authentication, therefore the page should be open the the general public. I have already created a "Seller" page where a seller can manage their own listings. so how can I create a link on each listing on my homepage that connects the
<p><%= "Sold by #{listing.user.name}" %></p>
the new show page for that user? thanks!
my listings_controller:
class ListingsController < ApplicationController
before_action :set_listing, only: [:show, :edit, :update, :destroy]
before_filter :authenticate_user!, only: [:seller, :new, :create, :edit, :update, :destroy]
before_filter :check_user, only: [:edit, :update, :destroy]
def seller
#listings = Listing.where(user: current_user).order("created_at DESC")
end
# GET /listings
# GET /listings.json
def index
if params[:category].blank?
#listings = Listing.all.order("created_at DESC").paginate(:page => params[:page], :per_page => 16)
else
#category_id = Category.find_by(name: params[:category]).id
#listings = Listing.where(category_id: #category_id).order("created_at DESC").paginate(:page => params[:page], :per_page => 16)
end
end
# GET /listings/1
# GET /listings/1.json
def show
end
# GET /listings/new
def new
#listing = Listing.new
end
# GET /listings/1/edit
def edit
end
# POST /listings
# POST /listings.json
def create
#listing = Listing.new(listing_params)
#listing.user_id = current_user.id
if current_user.recipient.blank?
Stripe.api_key = ENV["STRIPE_API_KEY"]
token = params[:stripeToken]
recipient = Stripe::Recipient.create(
:name => current_user.name,
:type => "individual",
:bank_account => token
)
current_user.recipient = recipient.id
current_user.save
end
respond_to do |format|
if #listing.save
format.html { redirect_to #listing, notice: 'Listing was successfully created.' }
format.json { render :show, status: :created, location: #listing }
else
format.html { render :new }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /listings/1
# PATCH/PUT /listings/1.json
def update
respond_to do |format|
if #listing.update(listing_params)
format.html { redirect_to #listing, notice: 'Listing was successfully updated.' }
format.json { render :show, status: :ok, location: #listing }
else
format.html { render :edit }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end
# DELETE /listings/1
# DELETE /listings/1.json
def destroy
#listing.destroy
respond_to do |format|
format.html { redirect_to listings_url, notice: 'Listing was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_listing
#listing = Listing.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def listing_params
params.require(:listing).permit(:name, :category_id, :description, :price, :image)
end
def check_user
if current_user != #listing.user
redirect_to root_url, alert: "Sorry, this listing belongs to someone else"
end
end
end
my current routes:
Rails.application.routes.draw do
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
resources :categories
devise_for :users
resources :listings do
resources :orders, only: [:new, :create]
end
get 'pages/about'
get 'pages/contact'
get 'seller' => "listings#seller"
get 'sales' => "orders#sales"
get 'purchases' => "orders#purchases"
# or
root 'listings#index'
end
and finally, my listing model:
class Listing < ActiveRecord::Base
if Rails.env.development?
has_attached_file :image, :styles => { :medium => "200x", :thumb => "100x100>" }, :default_url => "404.jpg"
else
has_attached_file :image, :styles => { :medium => "200x", :thumb => "100x100>" }, :default_url => "404.jpg",
:storage => :dropbox,
:dropbox_credentials => Rails.root.join("config/dropbox.yml"),
:path => ":style/:id_:filename"
end
validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
validates :name, :category_id, :description, :price, presence: true
validates :price, numericality: { greater_than: 0}
validates_attachment_presence :image
belongs_to :user
belongs_to :category
has_many :orders
end
my index page where I want to link to the seller specific page
<div class="center">
<div class="row">
<% #listings.each do |listing| %>
<div class="col-md-3">
<div class="thumbnail">
<%= link_to image_tag(listing.image.url), listing %>
<div class="caption">
<h3><%= listing.name %></h3>
<p><%= number_to_currency(listing.price) %></p>
<p><%= "Sold by #{listing.user.name}" %></p>
</div>
</div>
</div>
<% end %>
</div>
</div>
<br>
<div class="center">
<%= will_paginate #posts, renderer: BootstrapPagination::Rails %>
</div>
<% if user_signed_in? %>
<div class="right">
<%= link_to new_listing_path, class: "btn btn-primary", data: { no_turbolink: true } do %>
<i class="glyphicon glyphicon-plus"></i> New Listing
<% end %>
</div>
<% end %>
<br>
'User' is a model that you have created: devise only manages sessions, registrations, passwords, unlocks, and confirmations (the gem provides a controller for each one of these).
You should create your own UsersController, in which you can define the show action that you need. You should also declare a different path in your routes, or you'd have a conflict as '/users' is already used by devise. Something like
resources :users, only: [:show], path: 'sellers'
Then you can use
<p><%= "Sold by #{link_to listing.user.name, user_path(listing.user)}" %></p>
New to web development and have been trying to solve this for 4 days now - been through every solution here on StackOverflow but none of the answers have worked for me.
I am creating an application that allows users to upload an attachment and photo through Paperclip. Authentication and Authorization through Devise and CanCan
From a edit page, a user can click on a link to open an 'edit' page. From there he can see a form to browse and choose an image to upload. When clicking on the button, it calls the 'update' action and then renders the users show page, the image is saved to a tmp folder but does not insert to the Database.
Here is my User Model
class User < ActiveRecord::Base
has_and_belongs_to_many :roles
has_attached_file :avatar, styles: {
thumb: '50x50>',
square: '200x200#',
medium: '300x300>'
}
def role?(role)
return !!self.roles.find_by_name(role.to_s.camelize)
end
# Validate the attached image is image/jpg, image/png, etc
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable
end
User Controller
class UsersController < ApplicationController
before_action :get_user, :only => [:index, :new, :edit]
before_action :accessible_roles, :only => [:new, :edit, :show, :update, :create]
load_and_authorize_resource :only => [:show, :new, :destroy, :edit, :update]
def index
#users = User.accessible_by(current_ability, :index).limit(20)
respond_to do |format|
format.json { render :json => #users }
format.xml { render :xml => #users }
format.html
end
end
def new
respond_to do |format|
format.json { render :json => #users }
format.xml { render :xml => #users }
format.html
end
end
def show
#user = User.find(params[:id])
respond_to do |format|
format.json { render :json => #users }
format.xml { render :xml => #users }
format.html
end
rescue ActiveRecord::RecordNotFound
respond_to_not_found(:json, :xml, :html)
end
def edit
respond_to do |format|
format.json { render :json => #users }
format.xml { render :xml => #users }
format.html
end
rescue ActiveRecord::RecordNotFound
respond_to_not_found(:json, :xml, :html)
end
def destroy
#user.destroy!
respond_to do |format|
format.json { respond_to_destroy(:ajax) }
format.xml { head :ok }
format.html { respond_to_destroy(:html) }
end
rescue ActiveRecord::RecordNotFound
respond_to_not_found(:json, :xml, :html)
end
def create
#user = User.new(user_params)
if #user.save
respond_to do |format|
format.json { render :json => #users.to_json, :status => 200 }
format.xml { head :ok }
format.html { redirect_to :action => :index }
end
else
respond_to do |format|
format.json { render :text => "Could not create user", :status => :unprocessable_entity }
format.xml { head :ok }
format.html { render :action => :new, :status => :unprocessable_entity }
end
end
end
def update
if params[:user][:password].blank?
[:password, :password_confirmation, :current_password].collect{|p| params[:user].delete(p) }
else
#user.errors[:base] << "The password you entered is incorrect" unless #user.valid_password?(params[:user][:current_password])
end
respond_to do |format|
if #user.errors[:base].empty? and #user.update_attributes(user_params[:user])
flash[:notice] = "Your account has been updated"
format.json { render :json => #user.to_json, :status => 200 }
format.xml { head :ok }
format.html { render :action => :show }
else
format.json { render :text => "Could not update user", :status => :unprocessable_entity }
format.xml { render :xml => #user.errors, :status => :unprocessable_entity }
format.html { render :action => :edit, :status => :unprocessable_entity }
end
end
rescue ActiveRecord::RecordNotFound
respond_to_not_found(:json, :xml, :html)
end
private
def accessible_roles
#accessible_roles = Role.accessible_by(current_ability, :read)
end
def get_user
#user = current_user
end
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation, :avatar, :resume)
end
end
Here is the form code:
<%= form_for #user, :html => { :multipart => true } do |f| %>
<div class="field">
<%= f.label :avatar, "Photo" %>
<%= f.file_field :avatar %>
<%= f.submit "Submit" %>
</div>
<% end %>
I can not even seem to get it to display the temp image.
Any help will be much appreciated!
Show.html.erb
<%= image_tag #user.avatar.url(:medium) %>
<%= #user.email %>
I got a NoMethodError when i called <%= #post.admin_user.name %>, don't know how to fix it.
Extracted source (around line #4):
<h1><%= #post.title %></h1>
<p><%= #post.body %></p>
<small>Post created at <%= #post.created_at.strftime('%b %d. %Y') %></small><br/><br/>
<%= #post.admin_user.name %>
<p>Category: <%= link_to #post.category.name, category_path(#post.category.id) %></p>
<%= link_to 'Edit Post', edit_post_path %> | <%= link_to 'Go Back', posts_path %> | <%= link_to 'Delete Post', #post, :confirm => "Don't do it man!", :method => :delete %>
</div>
Showing c:/Sites/blog/app/views/posts/show.html.erb where line #5 raised:
undefined method `name' for nil:NilClass
This is my posts_controller.rb
class PostsController < ApplicationController
def index
#post = Post.all
end
def new
#post = Post.new
#category = Category.all
end
def create
#post = Post.new(post_params)
if #post.save
redirect_to posts_path, :notice => 'Your post has been posted!'
else
render 'new'
end
end
def post_params
params.require(:post).permit(:title, :body, :category_id, :admin_user_id, :admin_user, :name)
end
def edit
#post = Post.find(params[:id])
end
def update
#post = Post.find(params[:id])
if #post.update_attributes(post_params)
redirect_to post_path, :notice => 'Your post has been updated.'
else
render 'new'
end
end
def show
#post = Post.find(params[:id])
#user = AdminUser.all
end
def destroy
#post = Post.find(params[:id])
#post.destroy
redirect_to posts_path, :notice => 'Your post has been deleted.'
end
end
This is my post.rb
class Post < ActiveRecord::Base
belongs_to :category
belongs_to :admin_user
end
My admin_user.rd
class AdminUser < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable,
:recoverable, :rememberable, :trackable, :validatable
has_many :posts
end