Skip to content

Instantly share code, notes, and snippets.

@px-amaac
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save px-amaac/e0e9facb6cd34b6ebdc5 to your computer and use it in GitHub Desktop.
Save px-amaac/e0e9facb6cd34b6ebdc5 to your computer and use it in GitHub Desktop.
Simple has_many :through
<%= form_for @photo, :html => { :multipart => true } do |photo| %>
<div class="field">
<%= photo.label :title %>
<%= photo.text_field :title %>
</div>
<div class="field">
<%= photo.file_field :image %>
</div>
<%= photo.fields_for :tags do |tag| %>
<div class="field">
<%= tag.label :key %>
<%= tag.text_field :key %>
</div>
<div class="field">
<%= tag.label :value %>
<%= tag.text_field :value %>
</div>
<% end %>
<div class="actions">
<%= photo.submit %>
</div>
<% end %>
class Photo < ActiveRecord::Base
belongs_to :user
has_many :tag_photo_relationships, dependent: :destroy
has_many :tags, :through => :tag_photo_relationships
accepts_nested_attributes_for :tags
has_attached_file :image, :styles => {
:medium => "300x300>", :thumb => "100x100>" }
validates_attachment :image, :attachment_presence => true
# Validate content type
validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
# Validate filename
validates_attachment_file_name :image, :matches => [/png\Z/, /jpe?g\Z/]
end
class PhotosController < ApplicationController
before_action :set_photo, only: [:show]
before_action :correct_user, only: [ :edit, :update, :destroy ]
before_action :authenticate_user!
# GET /photos
# GET /photos.json
def index
@photos = current_user.photos
end
# GET /photos/1
# GET /photos/1.json
def show
@tags = @photo.tags
end
# GET /photos/new
def new
@photo = current_user.photos.build
@tag = @photo.tags.build
end
# GET /photos/1/edit
def edit
end
# POST /photos
# POST /photos.json
def create
@photo = current_user.photos.create(photo_params)
respond_to do |format|
if @photo.save
format.html { redirect_to @photo, notice: 'Photo was successfully created.' }
format.json { render :show, status: :created, location: @photo }
else
format.html { render :new }
format.json { render json: @photo.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /photos/1
# PATCH/PUT /photos/1.json
def update
respond_to do |format|
if @photo.update(edit_photo_params)
format.html { redirect_to @photo, notice: 'Photo was successfully updated.' }
format.json { render :show, status: :ok, location: @photo }
else
format.html { render :edit }
format.json { render json: @photo.errors, status: :unprocessable_entity }
end
end
end
# DELETE /photos/1
# DELETE /photos/1.json
def destroy
@photo.image = nil
@photo.save
@photo.destroy
respond_to do |format|
format.html { redirect_to photos_url, notice: 'Photo was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_photo
@photo = Photo.find(params[:id])
end
def correct_user
@photo = current_user.photos.find_by(id: params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def photo_params
params.require(:photo).permit(:title, :image, :tags_attributes => [:id, :key, :value])
end
def edit_photo_params
params.require(:photo).permit(:title)
end
end
<div class="panel row">
<p id="notice"><%= notice %></p>
<p>
<strong>Title:</strong>
<%= @photo.title %>
</p>
<%= image_tag (@photo.image.url(:medium)) %>
<p>
<strong>User:</strong>
<%= @photo.user.username %>
</p>
<%= link_to 'Edit', edit_photo_path(@photo), :class => "button radius round tiny" %> |
<%= link_to 'Destroy', @photo, method: :delete, data: { confirm: 'Are you sure?' }, :class => "button tiny alert radius round tiny" %> |
<%= link_to 'Back', photos_path, :class => "button [succes tiny radius round ]" %>
<h3>Tags</h3>
<% @tags.each do |tag| %>
<%= tag.key %>
<% end %>
</div>
class Tag < ActiveRecord::Base
has_many :tag_photo_relationships
has_many :photos, :through => :tag_photo_relationships
validates :key, presence: true, length: { in: 5..25 }, uniqueness: { case_sensitive: false }
validates :value, presence: true, length: { in: 5..25 }
end
class TagPhotoRelationship < ActiveRecord::Base
belongs_to :tag
belongs_to :photo
end
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_attached_file :avatar, :styles => {
:medium => "300x300>", :thumb => "100x100>" }
has_many :photos, :dependent => :destroy
#validates :avatar, :attachment_presence => true
#validates_with AttachmentSizeValidator, :attributes => :avatar, :less_than => 1.megabytes
# Validate content type
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
# Validate filename
validates_attachment_file_name :avatar, :matches => [/png\Z/, /jpe?g\Z/]
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment