I looked around a lot and found only one question like the one I am asking, And the information in it did not help me with my issues. What I am having an issue with is my users, I have several users. You're able to navigate to the page that displays every user, each one is clickable. But when ever I'm signed in to a user say Profile(1) and I wanna visit Profile(2) page it just loads Profile(1)'s credentials. Age, Bio, and Picture. Whats my issues here? It may be a simple fix and if so then thank you for the help in advance!
This is the page that list all users index.html.erb,
<div class="all_users">
<div class="container">
<p id="notice"><%= notice %></p>
<h1>Listing Users</h1>
<table>
<thead>
<tr>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #users.each do |user| %>
<ul class="media-list">
<li class="media">
<div class="media-left">
<%= link_to image_tag user.profile_picture.url(:thumb) %>
</a>
</div>
<div class="media-body">
<h4 class="media-heading">Name: <%= link_to user.first_name, dashboard_path %></h4>
<p>Age: <%= user.age %></p>
<p><%= user.bio %></p>
</div>
</li>
</ul>
<tr>
<td><%= link_to 'Show', user %></td>
<td><%= link_to 'Edit', edit_user_path(user) %></td>
<td><%= link_to 'Destroy', #user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br/>
<%= link_to 'New User', new_user_path %>
<%= link_to 'Login', login_path %>
</div>
</div>
Here is the profile page for the users show.html.erb,
<div class="show">
<div class="col-md-3">
<div class="thumbnail">
<% else %>
<%= image_tag #user.profile_picture.url(:medium) %>
<div class="caption">
<h2><%= #user.name %></h2>
<p>Message This User <i class="fa fa-envelope-o fa-lg"> </i></p>
<p>Report This User <i class="fa fa-exclamation fa-lg"> </i></p>
<p>Block this User <i class="fa fa-user-times fa-lg"> </i></p> <p>Add As Friend Follow</p>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">Bio for <%= #user.first_name %></div>
<p class="bio">
<%= #user.bio %>
</p>
</div>
</div>
<div class="col-md-4">
<div class="panel panel-default">
<%= form_for :post, url: posts_path do |f| %>
<div class="panel-heading">
<i class="fa fa-pencil-square"></i> <%= f.label :Status %> |<br>
</div>
<div class="panel-body">
<%= f.text_area :body, placeholder: "What's new?" %>
</div>
<p>
<%= f.submit %>
</p>
<% end %>
</div>
<%- #posts.each do |post| %>
<div class="panel panel-default">
<div class="panel-heading-gray"> <%= image_tag #user.profile_picture.url(:thumb) %> <h5 class="user-name"><%= #user.name %></h5> <h6 class="time-posted"><%= post.created_at.strftime("%B, %d, %Y") %></h6></div>
<div class="panel-body"><%= link_to post.body, post %></div>
<div class="panel-footer">
<%= render post.comments %>
<p class="Like-option">Like ·</p>
<p class="comment-form">Comment</p>
<p class="view-option">· View</p>
<p class="comment-profile-picture">
<%= image_tag #user.profile_picture.url(:thumb) %>
</p>
<%= #post.comments.count %>
<div id="comments-form">
<%= render "comments/form", :post => post %>
</div>
</div>
</div>
<% end %>
</div>
Here is my users_controller.rb,
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
after_action :signed_in_after_register, only: :create
def index
#users = User.all
#user = User.find(session[:user_id])
end
def dashboard
#user = User.find(session[:user_id]) unless session[:user_id] == ""
redirect_to login_path, notice: "You're not logged in" unless #user
#posts = #user.posts.order("created_at DESC").limit(3)
#comment = Comment.new
#post = Post.new
end
def newsfeed
#user = User.find(session[:user_id]) unless session[:user_id] == nil
redirect_to login_path, notice: "You're not logged in" unless #user
#posts = #user.posts.order("created_at DESC").limit(3)
end
def nav
#user = User.find(session[:user_id])
end
def posts
#user = User.find(session[:user_id])
#posts = #user.posts
end
def destroy
#user = User.find(session[:user_id]) unless session[:user_id] == ""
redirect_to login_path, notice: "You're not logged in" unless #user
end
def welcome
#user = User.find(session[:user_id]) unless session[:user_id] == ""
redirect_to login_path, notice: "You're not logged in" unless #user
end
def show
#user = User.find(params[:user_id]) unless session[:user_id] == ""
redirect_to login_path, notice: "You're not logged in" unless #user
#posts = #user.posts.order("created_at DESC").limit(3)
#comment = Comment.new
#post = Post.new
end
def new
#post = Post.new(params[:post_id])
#user = User.new
end
def edit
end
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to dashboard_path, notice: 'User was successfully created!' }
format.json { render :show, status: :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to dashboard_path, notice: 'User was successfully updated.' }
format.json { render :show, status: :ok, location: #user }
else
format.html { render :edit }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_user
#user = User.find(params[:id])
end
def signed_in_after_register
session[:user_id] = #user.id
end
def user_params
params.require(:user).permit(:first_name, :last_name, :bio, :password, :password_confirmation, :email, :age, :profile_picture, :post, :body)
end
end
and this is my user model user.rb,
class User < ActiveRecord::Base
has_secure_password
validates :first_name, :last_name, :email, presence: true, uniqueness: true
validates_inclusion_of :age, in: 10..100
validates :password, presence: true
has_many :posts
has_attached_file :profile_picture, :styles => { :medium => "300x300>", :thumb => "100x100>" },
:default_url => "app/assets/images/missing.png",
:path => ":rails_root/public/system/:class/:attachment/:id_partition/:style/:filename"
validates_attachment_content_type :profile_picture, :content_type => /\Aimage\/.*\Z/
I tried putting in User.find(params[:user_id]) and I get the following error
ActiveRecord::RecordNotFound in UsersController#show
Couldn't find User with 'id'=
EDIT: Here is my routes file,
Rails.application.routes.draw do
root 'welcome#welcome'
get 'login' => 'sessions#login', :as => :login
get 'dashboard' => 'users#dashboard', :as => :dashboard
post 'logging/user' => 'sessions#create'
get 'logout' => 'sessions#destroy', :as => :logout
get 'about' => 'about'
get 'newsfeed' => 'users#newsfeed'
resources :users, except: :show
get 'profile/:id' => 'users#show', as: :profile
resources :posts do
resources :comments
end
get 'index' => 'posts#index'
get 'register' => 'users#new', :as => :register
end
Which link are you clicking to view a user's profile?
<h4 class="media-heading">Name: <%= link_to user.first_name, dashboard_path %></h4>
or:
<td><%= link_to 'Show', user %></td>
If it's the first one why are you linking to dashboard_path? Seems like that should be linking to user_path(user) right?
Might also help to show us your routes file.
Related
I have an app that allows users to add albums they like to a database. Anyone can then come along and write a review for that album. Pretty simple.
I am running into a problem where an extra record appears to be created for the reviews on each album's show page. Every album, even if it has not ever been reviewed, has an additional, seemingly empty review being displayed when I use .each to display each review in the album show page. I want to get rid of that.
Here is an image of the problem. I have used CSS to highlight reviews in red. As you can see, there is an empty review at the bottom. When I inspect the review in question, it's raty title is "Not reviewed yet!"
Here is my albums_controller:
class AlbumsController < ApplicationController
before_action :set_album, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, only: [:edit, :new, :update, :destroy]
def index
#albums = Album.all
if params[:search].nil?
#albums = Album.all.order(year: :desc).order(title: :asc).paginate(:page => params[:page], :per_page => 24)
else
#albums = #albums.where("albums.title || albums.year || albums.artist LIKE ?", "%#{params[:search]}%").order(year: :desc).order(title: :asc).paginate(:page => params[:page], :per_page => 24)
end
end
def show
if #album.reviews.blank?
#average_review = 0
else
#average_review = #album.reviews.average(:rating).round(2)
end
#review = #album.reviews.build
end
def new
#album = Album.new
end
def edit
end
def create
#album = current_user.albums.build(album_params)
respond_to do |format|
if #album.save
format.html { redirect_to #album, notice: 'Album was successfully created.' }
format.json { render :show, status: :created, location: #album }
else
format.html { render :new }
format.json { render json: #album.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #album.update(album_params)
format.html { redirect_to #album, notice: 'Album was successfully updated.' }
format.json { render :show, status: :ok, location: #album }
else
format.html { render :edit }
format.json { render json: #album.errors, status: :unprocessable_entity }
end
end
end
def destroy
#album.destroy
respond_to do |format|
format.html { redirect_to albums_url, notice: 'Album was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_album
#album = Album.find(params[:id])
end
def album_params
params.require(:album).permit(:title, :artist, :year, :cover)
end
end
Here is the album show page, which is where the extra review is being displayed:
<div class="row">
<div class="col-xs-10 col-md-6 col-md-push-3 col-xs-push-1 top bottom">
<%= image_tag #album.cover, class: 'show_image' %>
<h2><%= #album.title %></h2>
<h4><%= #album.artist %></h4>
<h5><%= #album.year %></h5>
<p class="white">Average Review<div class="average-review-rating" data-score=<%= #average_review %>></div></p>
<% if user_signed_in? %>
<% if #album.user_id == current_user.id %>
<%= link_to 'Edit', edit_album_path(#album), class: 'grey' %>
| <%= link_to 'Delete', album_path, method: :delete, data: {confirm: "Are you sure?"}, class: 'grey' %>
<% end %>
<% end %>
<br /><br />
<h4>Reviews</h4>
<% if user_signed_in? %>
<p class="grey">Write a review</p>
<%= form_for [#album, #review] do |r| %>
<div class="form-group">
<div id="rating-form">
<label>Rating</label>
</div>
</div>
<div class="form-group">
<%= r.text_area :comment, class: 'form-control', placeholder: "Write a comment" %>
</div>
<div class="form-group">
<%= r.submit "Create", class: 'btn btn-success' %>
</div>
<% end %>
<% end %>
<br />
<% #album.reviews.each do |r| %>
<div class="red">
<div class="review-rating" data-number="<%= r.rating %>">
</div>
<p class="white"><%= r.comment %></p>
<% if user_signed_in? %>
<% if current_user.id == r.user_id %>
<%= link_to 'Edit', edit_album_review_path(#album, r.id), class: 'grey' %> |
<%= link_to 'Delete', album_review_path(#album, r.id), method: :delete, data: {confirm: "Are you sure?"}, class: 'grey' %>
<% end %>
<% end %>
<br /><br />
</div>
<% end %>
</div>
</div>
<script>
$('.review-rating').raty({
readOnly: true,
score: function() {
return $(this).attr('data-number');
},
path: '/assets/'
});
$('#rating-form').raty({
path: '/assets/',
scoreName: 'review[rating]'
});
$('.average-review-rating').raty({
readOnly: true,
path: '/assets/',
score: function() {
return $(this).attr('data-score')
}
});
</script>
Any help would be very appreciated!
The problem here is on the last line of your show method: #review = #album.reviews.build. This line not only creates a new Review instance and assigns it to #review, but it also adds that instance to the array in #album.reviews. So, in your view, when you iterate over #album.reviews, you will see all of the persisted reviews as well as the one new, not persisted review that was built with build.
The easiest way to fix this would be to add this line in your view:
<% #album.reviews.each do |r| %>
<% next unless r.persisted? %>
Another solution would be to associate the new review with the album, but not on the #album instance. In the controller:
#review = Review.new(album: #album)
I think it could be because of last line in show.
#review = #album.reviews.build
It builds an empty review.
I have a sidebar which displays the user's constructions.
I display it this way:
<% current_user.constructions.each do |obra| %>
<li>
<%= link_to construction_path(obra) do %>
<i class="fa fa-home"></i> <%= obra.name %>
<% end %>
<ul class="nav child_menu" style="display: block">
<li>
<%= link_to "Documentos", construction_docs_path(obra) %>
</li>
<li>
<%= link_to "Meus Pagamentos", construction_boletos_path(obra) %>
</li>
</ul>
</li>
<% end %>
It's working with everything, except when I try to create a New Construction, it says:
No route matches {:action=>"show", :controller=>"constructions", :id=>nil}
missing required keys: [:id]
I guess that's because it loses track of the current_user.constructions since my controller makes the
def new
#construction = current_user.constructions.build
end
call...
How can I pass the current constructions' ids, displaying it at the same time that I create a new construction?
EDIT -
constructions_controller.rb
class constructionsController < ApplicationController
before_filter :authenticate_user!
before_action :set_construction, only: [:show, :edit, :update, :destroy]
# GET /constructions
# GET /constructions.json
def index
#constructions = Construction.all
end
# GET /constructions/1
# GET /constructions/1.json
def show
end
# GET /constructions/new
def new
#construction = current_user.constructions.build
end
# GET /constructions/1/edit
def edit
end
# POST /constructions
# POST /constructions.json
def create
#construction = current_user.constructions.build(construction_params)
respond_to do |format|
if #construction.save
format.html { redirect_to #construction, notice: 'construction was successfully created.' }
format.json { render :show, status: :created, location: #construction }
else
format.html { render :new }
format.json { render json: #construction.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /constructions/1
# PATCH/PUT /constructions/1.json
def update
respond_to do |format|
if #construction.update(construction_params)
format.html { redirect_to #construction, notice: 'construction was successfully updated.' }
format.json { render :show, status: :ok, location: #construction }
else
format.html { render :edit }
format.json { render json: #construction.errors, status: :unprocessable_entity }
end
end
end
# DELETE /constructions/1
# DELETE /constructions/1.json
def destroy
#construction.destroy
respond_to do |format|
format.html { redirect_to constructions_url, notice: 'construction was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_construction
#construction = Construction.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def construction_params
params.require(:construction).permit(:name, :locale, :start_date, :description, :image)
end
end
routes.rb
Rails.application.routes.draw do
resources :boletos
resources :documentos
resources :constructions do
get 'construction_documents/index', :path => 'docs', :as => 'docs'
get 'construction_boletos/index', :path => 'boletos', :as => 'boletos'
end
devise_for :users
root 'plainpage#index'
end
constructions/new.html.erb
<h1>New Construction</h1>
<%= render 'form' %>
<%= link_to 'Back', constructions_path %>
constructions/_form.html.erb
<%= form_for #construction, html: { multipart: true } do |f| %>
<% if #construction.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#construction.errors.count, "error") %> prohibited this construction from being saved:</h2>
<ul>
<% #construction.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.file_field :image %>
</div>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :locale %><br>
<%= f.text_field :locale %>
</div>
<div class="field">
<%= f.label :start_date %><br>
<%= f.date_select :start_date %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_area :description %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I am trying to improve an exercice that I did on treehouse, the idea was to remake a little version of facebook thing, where users could publish statuses.
Now I want that a user can comment any statuses... And I am kinda lost...
The idea is to have all on the same page (if possible?, like on the real facebook)
So the comment form and the "displaying" content...
I hope anyone could help me :)
This is my github repository
I think I haven't understand how to call variables from a controller to another...
If someone could explain me with very easy words ... I am not native english speaker... so sometime it's difficult..
Here are the statuses part
controllers/statuses_controller/rb
class StatusesController < ApplicationController
before_filter :authenticate_user!, only: [:new, :create, :edit, :update]
before_action :set_status, only: [:show, :edit, :update, :destroy]
def index
#statuses = Status.all
#comments = Comment.all
end
def show
#status = Status.find(params[:id])
#comments = #status.comments.all
end
def new
#status = Status.new
#comment = #status.comments.build
end
def create
#status = Status.new(status_params)
#status.user = current_user
respond_to do |format|
if #status.save
format.html { redirect_to #status, notice: 'Status was successfully created.' }
format.json { render :show, status: :created, location: #status }
else
format.html { render :new }
format.json { render json: #status.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #status.update(status_params)
format.html { redirect_to #status, notice: 'Status was successfully updated.' }
format.json { render :show, status: :ok, location: #status }
else
format.html { render :edit }
format.json { render json: #status.errors, status: :unprocessable_entity }
end
end
end
def destroy
#status.destroy
respond_to do |format|
format.html { redirect_to statuses_url, notice: 'Status was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_status
#status = Status.find(params[:id])
end
def status_params
params.require(:status).permit(:user_id, :content, :comments_attribute[:id, :status_id, :content])
end
end
models/status.rb
class Status < ActiveRecord::Base
belongs_to :user
has_many :comments
default_scope -> { order(created_at: :DESC)}
validates :content, presence: true,
length: {minimum: 2}
validates :user_id, presence: true
end
views/comments/_form.html.erb I create a render in my index below:
<% simple_form_for #status.comments do |f|%>
<%= f.input :content %>
<%= f.button :submit %>
<% end %>
view/statuses/index.html.erb
<div class="page-header">
<h1>All of the Statuses</h1>
</div>
<%= link_to "Post A New Status", new_status_path, class: "btn btn-success"%>
<br>
<br>
<% #statuses.each do |status| %>
<div class="status">
<div class="row">
<div class="col-xs-1 avatar">
<%= image_tag status.user.avatar.thumb if status.user.avatar?%>
</div>
<div class="col-xs-7">
<h4><%= status.user.full_name%></h4>
</div>
</div>
<div class="row">
<div class="col-xs-8">
<p><%= simple_format(status.content) %></p>
</div>
</div>
<div class="row">
<div class="col-xs-8">
<%= link_to time_ago_in_words(status.created_at) + " ago", status %>
<% if status.user == current_user %>
<span class="admin">
| <%= link_to "Edit", edit_status_path(status) %> |
<%= link_to "Delete", status, method: :delete, data: {confirm: "Are you sure?"} %>
</span>
<% end %>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<p>Comments</p>
<% #comments.each do |comment| %>
<%= comment.content %>
<% end %>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<%= render "comments/form" %>
</div>
</div>
</div>
Now the comments part:
model/comment.rb
class Comment < ActiveRecord::Base
belongs_to :status
belongs_to :user
end
controllers/comments_controller.rb
class CommentsController < ApplicationController
def create
#comment = Comment.new(params_comment)
end
def index
#statuses = Status.all
#comments = Comment.all
#comment = Comment.find_by(params[:id])
end
private
def params_comment
params.require(:comment).permit(:content)
end
end
routes.rb
resources :statuses do
resources :comments
end
user.rb
that's a part of what I have in there
has_many :statuses
has_many :comments
your comments creation method should look like this:
#status = Status.find(params[:status_id])
#comment = #status.comments.create(comment_params)
#comment.user_id = current_user.id if current_user
#comment.save
i'm making a Rails app that requires the use of a search form.
In my app, a user can create a post, 'Ad', and then specify if he wants it to be a small, medium or featured sized post.
This was working fine until I attempted to incorporate Sunspot Solr Search into my app.
No when ever I create a post, be it small, medium or featured, it creates on of every size whenever it should only create the selected one.
Ad Controller
class AdsController < ApplicationController
before_action :set_ad, only: [:show, :edit, :update, :destroy]
# GET /ads
# GET /ads.json
def index
#search_medium = Ad.where(:size => "medium").search do
fulltext params[:search]
end
#search_featured = Ad.where(:size => "featured").search do
fulltext params[:search]
end
#search_small = Ad.where(:size => "small").search do
fulltext params[:search]
end
#ads = Ad.all
#ads_small = #search_small.results
#ads_medium = #search_medium.results
#ads_featured = #search_featured.results
end
# GET /ads/1
# GET /ads/1.json
def show
end
# GET /ads/new
def new
#ad = Ad.new
end
# GET /ads/1/edit
def edit
end
# POST /ads
# POST /ads.json
def create
#ad = Ad.new(ad_params)
#ad.user_id = current_user.id
respond_to do |format|
if #ad.save
format.html { redirect_to #ad, notice: 'Ad was successfully created.' }
format.json { render action: 'show', status: :created, location: #ad }
else
format.html { render action: 'new' }
format.json { render json: #ad.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /ads/1
# PATCH/PUT /ads/1.json
def update
respond_to do |format|
if #ad.update(ad_params)
format.html { redirect_to #ad, notice: 'Ad was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #ad.errors, status: :unprocessable_entity }
end
end
end
# DELETE /ads/1
# DELETE /ads/1.json
def destroy
#ad.destroy
respond_to do |format|
format.html { redirect_to ads_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_ad
#ad = Ad.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def ad_params
params.require(:ad).permit(:title, :url, :preview, :location, :size, :info)
end
end
My Index View
<style type="text/css">
.ads_link {
font-family: NexaBold, Helvetica, Arial, sans-serif;
color: #e74c3c!important;
}
</style>
<%= form_tag ads_path, :method => :get do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
<% end %>
<% #ads_featured.each do |ad| %>
<div class="adspace_grid_f">
<div class="pic_sec_f">
<%= image_tag ad.preview.url(:featured) %>
</div>
<div class="text_info_f">
<span class="bold"><%= link_to ad.title, ad, :class => "title" %></span></br>
<p><%= truncate(ad.info, length: 90) %></p>
<span class="bold"><%= ad.location %></span></br>
<span class="bold"><%= ad.url %></span>
</div>
<% if can? :destroy, ad %>
<%= link_to 'Delete', ad, :method => :delete, :class => "delete" %>
<% end %>
</div>
<% end %>
<% #ads_medium.each do |ad| %>
<div class="adspace_grid">
<div class="pic_sec">
<%= image_tag ad.preview.url(:medium) %>
</div>
<div class="text_info">
<span class="bold"><%= link_to ad.title, ad, :class => "title" %></span></br>
<p><%= truncate(ad.info, length: 60) %></p>
<span class="bold"><%= ad.location %></span></br>
<span class="bold"><%= ad.url %></span>
</div>
<% if can? :destroy, ad %>
<%= link_to 'Delete', ad, :method => :delete, :class => "delete" %>
<% end %>
</div>
<% end %>
<% #ads_small.each do |ad| %>
<div class="adspace_grid">
<div class="pic_sec">
<%= image_tag ad.preview.url(:medium) %>
</div>
<div class="text_info">
<span class="bold"><%= ad.title %></span></br>
<p><%= truncate(ad.info, length: 30) %></p>
<div class="right-text">
<span class="bold"><%= ad.location %></span></br>
<span class="bold"><%= ad.url %></span>
</div>
</div>
<% if can? :destroy, ad %>
<%= link_to 'Delete', ad, :method => :delete %>
<% end %>
</div>
<% end %>
My Model File
class Ad < ActiveRecord::Base
attr_accessible :title, :url, :preview, :size, :location, :info
belongs_to :user
has_attached_file :preview, :default_url => "missing.jpg", :styles => { :medium => "125x125^", :featured => "250x250^", :showpg => "400x400^" }, :convert_options => {:medium => "-gravity center -extent 125x125", :featured => "-gravity center -extent 250x250", :showpg => "-gravity center -extent 400x400"}
validates :title, length: { maximum: 35 }
validates :url, length: { maximum: 40 }
searchable do
text :title, :info
end
end
the local sunspot server is running on the port 8983 by default, and it provide a web admin there. You can do a search by entering the query as ":", and this will return all the indexed record inside sunspot.
I suggest you add the size field into the searchable definition and do the search without the where method call.
So, I have a rails app that allows users to submit youtube links and rank the songs/links using the thumbs up gem.
However, users must physically copy and paste the link into the browser to listen to the song after the link is uploaded. For a better UX I'm going to use this gem to dynamically embed the YouTube video into my app once the users upload the link.
However, I'm not quite sure how this can be done?
I was thinkin' of doing something like this in the index:
<%= YouTubeAddy.extract_video_id('song.url)' %> <%= YouTubeAddy.youtube_embed_url('song.url') %> ?
or would it have to be in the controller? and if so how?
song#new.html.erb:
<%= form_for #song, :html => { :multipart => true } do |f| %>
<% if #song.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#song.errors.count, "error") %> prohibited this song from being saved:</h2>
<ul>
<% #song.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="row">
<div class="large-6 columns">
<div class="field">
<%= f.label :title %>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label 'website url' %>
<%= f.text_area :url %>
</div>
<div class="field">
<%= f.label :tag_list, "Genres (separated by commas)" %><br />
<%= f.text_field :tag_list %>
</div>
<p>
<%= f.file_field :track%>
</p>
<div class="actions">
<%= f.submit value: "Upload" %>
</div>
<% end %>
</div>
song_controller.rb
class SongsController < ApplicationController
before_filter :authenticate_user!, only: [:create ,:edit, :update, :destroy, :vote_for_song]
before_action :set_song, only: [:show, :edit, :update, :destroy, :vote_for_song]
def vote_for
#song = Song.find(params[:id])
current_user.vote_for(#song)
#song.plusminus = #song.votes_for
#song.save
respond_to do |format|
format.js { render 'update_votes' }
end
end
def vote_against
#song = Song.find(params[:id])
current_user.vote_against(#song)
respond_to do |format|
format.js { render 'update_votes' }
end
end
def new_songs
#songs = Song.order "id DESC"
end
# GET /Songs
# GET /Songs.json
def index
if params[:genre]
#songs = Song.tagged_with(params[:genre]).paginate(:page => params[:page], :per_page => 15)
else
#songs = Song.order('plusminus').paginate(:page => params[:page], :per_page => 15)
end
end
# GET /Songs/1
# GET /Songs/1.json
def show
#comment = Comment.new(song: #song)
end
# GET /Songs/new
def new
#song = Song.new
end
# GET /Songs/1/edit
def edit
end
# POST /Songs
# POST /Songs.json
def create
#song = Song.new(song_params)
respond_to do |format|
if #song.save
format.html { redirect_to #song, notice: 'Song was successfully created.' }
format.json { render action: 'show', status: :created, location: #song }
else
format.html { render action: 'new' }
format.json { render json: #song.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /Songs/1
# PATCH/PUT /Songs/1.json
def update
respond_to do |format|
if #song.update(song_params)
format.html { redirect_to #song, notice: 'Song was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #song.errors, status: :unprocessable_entity }
end
end
end
# Song /Songs/1
# Song /Songs/1.json
def destroy
#song.destroy
respond_to do |format|
format.html { redirect_to songs_url }
format.json { head :no_content }
end
end
private
def set_song
#song = Song.find(params[:id])
end
def song_params
params.require(:song).permit(:title, :artist, :url, :track, :user_id, :tag_list)
end
end
index.html.erb
<h6>Top ranked songs</h6>
<hr>
<ol><% #songs.each do |song| %>
<span class="title">
<li><%=link_to image_tag('thumbs.png', size: '16x50'), vote_for_song_path(song), :remote => true, :method => :put %> <%= link_to song.title, song %><span class="subtext"> (<%= song.url %>)<br></li></span>
<%#=link_to '▼'.html_safe, vote_against_song_path(song), :remote => true, :method => :put %>
<span class="subtext"><span class="votes_<%= song.id %>"><%= pluralize(song.votes.count, 'like') %>,</span>
posted <%= time_ago_in_words(song.created_at) + " ago" %>
<small><span class="comments"></small> | <%= pluralize(song.comments.size, 'comment') %></span></small><br /></span>
<%#= link_to 'Show', song, class: "button small secondary" %>
<%= link_to('Edit', edit_song_path(song), class: "button small secondary") if can? :update, song %>
<%= link_to('Destroy', song, method: :delete, data: {confirm: 'Are you sure?'}, class: "button small secondary") if can? :destroy, song %>
<% end %>
</ol>
<div class="pagination-centered">
<ul class="pagination">
<%#= will_paginate #songs %>
<!-- or custom pagination -->
<% if #songs.previous_page %>
<%= link_to "Back", params.merge(page: #songs.previous_page) %>
<% end %>
<% if #songs.next_page %>
<%= link_to "More", params.merge(page: #songs.next_page) %>
<% end %>
</ul></div>
YouTubeAddy.youtube_embed_url('song.url') generates a string of iframe tag, so it should be used in your view exactly where you want an embedded video to be placed. But note that you should return an html safe string. So in your view you have:
<%=raw YouTubeAddy.youtube_embed_url('song.url') %>
More about unescaping html.