i have a simple dating application am designing, and my users model has two boolean fields for male and female, i want a situation when a user signs up as Male, Female users should be shown to him to add as friends and if its a female too, male users should be shown. my users model is as follow
t.string :email, :null => false, :default => ""
t.string :bio, :null => false, :default => "update whatsup with yourself and click here to edit it"
t.string :username, :null => false, :default => ""
t.string :encrypted_password, :null => false, :default => ""
t.boolean :admin
t.boolean :author
t.boolean :male
t.boolean :female
and i have implemented the friendship model
In your controller action somewhere, add this bit.
#opposite_sex_users = nil
if current_user.male && !current_user.female
#opposite_sex_users = User.where(:male => false, :femail => true)
elsif !current_user.male && current_user.female
#opposite_sex_users = User.where(:male => true, :femail => false)
end
You haven't really given me enough information to solve your problem unfortunately. Assuming you want to use this in home action in pages controller for example, you can do something like this.
class PagesController < ApplicationController
def home
#opposite_sex_users = nil
number_of_users_to_show = 5 # change this to the number of users you want to show
if current_user.male && !current_user.female
#opposite_sex_users = User.where(:male => false, :femail => true).sample(number_of_users_to_show)
elsif !current_user.male && current_user.female
#opposite_sex_users = User.where(:male => true, :femail => false).sample(number_of_users_to_show)
end
end
end
And in your routes,
root :to => "pages#home"
And in your views/pages/home.html.erb
<%- #opposite_sex_users.each do |user| %>
<!-- displays user email %>
<%= user.username %>
<% end %>
Related
I'm building a friendship feature in my Rails/Angular app and currently I can create relations between users but I'm stuck on a small problem.
I have a friendships table,
create_table "friendships", force: :cascade do |t|
t.integer "user_id"
t.integer "friend_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
When a user adds another users as a friend a new record is created,
This is the index definition on the friendships_controller
def index
friend = current_user.friendships
render :json => friend.to_json()
end
And this is the json output.
{"id":1,"user_id":1,"friend_id":2,"created_at":"2015-12-29T13:18:44.499Z","updated_at":"2015-12-29T13:18:44.499Z"},
{"id":2,"user_id":1,"friend_id":3,"created_at":"2015-12-29T13:18:45.463Z","updated_at":"2015-12-29T13:18:45.463Z"},
{"id":3,"user_id":1,"friend_id":4,"created_at":"2015-12-29T13:18:46.420Z","updated_at":"2015-12-29T13:18:46.420Z"}
But this data is hardly usable. Is it possible to inject the user data in the friendship json?
{"id":1,"email":"peter#peter.nl","name":"Peter Boomsma"},
{"id":2,"email":"jan#jan.nl","name":"Jan Jansen"},
{"id":3,"email":"kees#kees.nl","name":"Kees Keesen"},
{"id":4,"email":"piet#piet.nl","name":"Piet Pietersen"}
So that the friendship json output looks like this,
{"id":1,"user_id":1,"friend_id":2,"email":"jan#jan.nl","name":"Jan Jansen","created_at":"2015-12-29T13:18:44.499Z","updated_at":"2015-12-29T13:18:44.499Z"},
{"id":2,"user_id":1,"friend_id":3,"email":"kees#kees.nl","name":"Kees Keesen","created_at":"2015-12-29T13:18:45.463Z","updated_at":"2015-12-29T13:18:45.463Z"},
{"id":3,"user_id":1,"friend_id":4,"email":"piet#piet.nl","name":"Piet Pietersen","created_at":"2015-12-29T13:18:46.420Z","updated_at":"2015-12-29T13:18:46.420Z"}
* REMOVE FUNCTION *
app.factory('removeFriend', ['$http', function($http) {
return {
removeFriend: function(friend) {
var _friendID = parseInt(friend.id);
console.log (_friendID)
return $http.delete('/friendships/'+_friendID + '.json');
}
};
}])
This is the remove service in angular, here it passes the friend.id and not the friendship.id.
I will implement something like following:
Add association in user model to get friends of the user i.e user objects
has_many :friends, through: :friendships, foreign_key: 'friend_id'
now get friends data in controller
friends = current_user.friends.as_json(:only => [:name, :email, :id])
render :json => friends # [{:name => 'test', :email => 'test#test.com', :id => 1},{...}]
If you need current user data in the response you can do something as following:
render :json => current_user.as_json(only: [:id, :name, :email]).merge(:friends => friends)
# {:id => 1, :name => 'user', :email => 'testuser#test.com', friends: [{:name => 'test', :email => 'test#test.com', :id => 1},{}]}
In above response you can send exact data required without repetition.
I am having trouble adding an object to associate class.
the parent class, user, has a has_many relation with the ad class.
When i try to access user's has_many object ":ads" from the ad controller, it returns me an "undefined method ads" exception. I am posting my model and my controller code below. Please help me on this issue.
user model
class User < ActiveRecord::Base
has_many :ads
has_secure_password
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "50x50#" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
def self.searchID(query)
where("id like ?", "#{query}")
end
end
ad model
class Ad < ActiveRecord::Base
belongs_to :user
scope :orderNewestFirst , lambda { order("id DESC") }
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100#" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
def self.search(query)
where("title like ?", "%#{query}%")
end
end
Ad Controller
class AdController < ApplicationController
layout false
before_action :confirm_logged_in
def index
#ads = Ad.orderNewestFirst
end
def new
#ad = Ad.new()
end
def create
#find = session[:user_id]
#user = User.searchID(#find)
#ad = Ad.new(ad_params)
if #user.ads << #ad #***this is where the error is occuring***
flash[:notice] = "Ad created Successfully"
redirect_to(:controller => 'user' , :action => 'index')
else
render('new')
end
end
def show
#ad = Ad.find(params[:id])
end
def ad_params
params.require(:ad).permit(:title, :category, :description , :priceRange, :avatar )
end
end
EDIT
Here are my migrations for User and Ad
User Migration
class CreateUsers < ActiveRecord::Migration
def up
create_table :users do |t|
t.string "firstName" , :limit => 50 , :null => false
t.string "lastName" , :limit => 50
t.string "email" , :null => false
t.string "password" , :limit => 30 , :null => false
t.integer "rating" , :default => 0
t.string "location" , :default => "Lahore"
t.timestamps null: false
end
end
def down
drop_table :users
end
end
#user = User.new(:firstName => "" , :lastName => "" , :email => "" , :password => "" , :rating => "" , :location => "")
Ad Migration
class CreateAds < ActiveRecord::Migration
def up
create_table :ads do |t|
t.references :user
t.string "title" , :null => false
t.string "category" , :null => false
t.text "description"
t.string "priceRange" , :null => false
t.attachment :avatar
t.timestamps null: false
end
add_index("ads" , "user_id")
end
def down
drop_table :ads
end
end
#ad = Ad.new(:title => "" , :category => "" , :description => "" , :priceRange => "")
The error that i get..
Your User.searchID(query) returns multiple user records (a relation object), not a single one.
If you change it to User.searchID(query).take, it fetches only a single record, and the error vanishes.
I don't know what value session[:user_id] holds, but looking at your users table, this would simply be an integer ID? In that case, there isn't much sense in the current approach. I'd recommend something like this:
def create
#user = User.find(session[:user_id])
# Rest of create method
end
The User.find method looks for a user record with that exact ID, and will return a single record straight away. This is one of the most common ways to fetch records using Ruby on Rails.
I am not sure how like query with id is working for you, In postgres it doesn't
def self.searchID(query)
where("id like ?", "#{query}")
end
You don't need above method you can find user directly by id as
#user = User.find(session[:user_id])
I have activeadmin installed and working fine for a 'reviews' section of may app, allowing me to add individual reviews to various locations in which my business is based. I tried to add the identical set up but using a BusinessReviews model rather than Reviews (thus allowing me to add business reviews on the same basis)
Everything works fine until I go into active admin (log in and accessing the 'Business Reviews' panel is fine, until I try and actually add a business review. I then get the error:
NoMethodError in Admin::BusinessReviews#new
undefined method `business_profile_image' for #<BusinessReview:0x007f893fe853d0>
My model is as follows:
class BusinessReview < ActiveRecord::Base
belongs_to :location
has_many :images, :as => :referrer
accepts_nested_attributes_for :images, :allow_destroy => true
def thumbnail
if self.images.count > 0
self.images.last.avatar(:thumb)
else
nil
end
end
end
my_app/admin/business_review.rb is as follows:
ActiveAdmin.register BusinessReview do
index do
column :business_reviewer_name
column :business_review_content
column :business_reviewer_address
column :rating
column :location do |business_review|
business_review.location.name
end
column :business_profile_image do |business_review|
image_tag(business_review.business_profile_image) if business_review.business_profile_image.present?
end
actions
end
show do |business_review|
attributes_table do
row :business_reviewer_name
row :business_profile_image
row :business_review_content
row :business_reviewer_address
row :rating
row :location do
business_review.location.name
end
end
panel "Images" do
table_for business_review.images do
column {|img| img.currently_used }
column {|img| image_tag(img.avatar.url(:large)) }
end
end
active_admin_comments
end
permit_params [:id, :business_reviewer_name, :business_profile_image, :business_review_content, :business_reviewer_address, :rating, :location_id], images_attributes: [:id,:_destroy,:avatar,:usage_type, :currently_used]
form do |f|
f.inputs 'Details' do
f.input :business_reviewer_name
f.input :business_profile_image
f.input :business_review_content
f.input :business_reviewer_address
f.input :rating
f.input :location
end
f.inputs "images" do
f.has_many :images, :allow_destroy => true, :heading => 'Images', :new_record => true do |imgf|
imgf.input :currently_used
imgf.inputs "Attachment", :multipart => true do
imgf.input :avatar, :as => :file, :hint => imgf.object.avatar? \
? imgf.template.image_tag(imgf.object.avatar.url(:large))
: imgf.template.content_tag(:span, "no image yet")
end
end
end
f.actions
end
end
Relevant part of my schema:
create_table "business_reviews", force: true do |t|
t.text "business_reviewer_content"
t.string "business_reviewer_name"
t.string "business_reviewer_address"
t.float "rating"
t.string "profile_image"
t.datetime "created_at"
t.datetime "updated_at"
end
The routes appear to be there ok too?
batch_action_admin_business_reviews POST /admin/business_reviews/batch_action(.:format) admin/business_reviews#batch
_action
admin_business_reviews GET /admin/business_reviews(.:format) admin/business_reviews#index
POST /admin/business_reviews(.:format) admin/business_reviews#creat
e
new_admin_business_review GET /admin/business_reviews/new(.:format) admin/business_reviews#new
edit_admin_business_review GET /admin/business_reviews/:id/edit(.:format) admin/business_reviews#edit
admin_business_review GET /admin/business_reviews/:id(.:format) admin/business_reviews#show
PATCH /admin/business_reviews/:id(.:format) admin/business_reviews#updat
e
PUT /admin/business_reviews/:id(.:format) admin/business_reviews#updat
e
DELETE /admin/business_reviews/:id(.:format) admin/business_reviews#destr
oy
I just don't get it as the reviews one I set up works perfectly and is identical (apart from the not haveing business_ appended to it).
According to your schema there is no business_profile_image but just profile_image:
t.string "profile_image"
So either rename the column or use profile_image instead of business_profile_image.
I'm very new to rails so please be detailed in your responses. I'm building a web app that uses devise for authentication. The part that I'm stuck on right now is a user to user messaging system. The idea is that User A logs into the app and can visit user B's profile, and on User B's profile can click on a link that allows User A to compose a message to User B. Then User B can log into the app and visit the inbox where User A's message will be found.
I believe that I'm having trouble defining the sender and recipient roles here, right now I'm trying to display the form that users will compose their message in. Can anyone see what I'm doing wrong here? I get the following error. I've read that the thing to do is add the User_id field to the table, but I'm hoping to link this messages up using sender_id and recipient_id, which both equal user_id (e.g. User 1[sender] sends a message to User 2 [recipient]):
unknown attribute: user_id
def new
#message = current_user.messages.new recipient_id: params[:sender_id]
end
Additionally, for you rails experts or anyone that has done something similar to this, can you advise whether or not I'm going in the right direction, or offer any guidance? I'm sort of coding blind here and just trying to make it up as I go along. Any guidance would be hugely appreciated and save me a lot of time i'm sure. Code below:
Users Migration
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
t.string :first_name
t.string :last_name
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
t.string :reset_password_token
t.datetime :reset_password_sent_at
t.datetime :remember_created_at
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
t.timestamps
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
end
end
Messages Migration
class CreateMessages < ActiveRecord::Migration
def change
create_table :messages do |t|
t.string :content
t.integer :sender_id
t.integer :recipient_id
t.timestamps
end
end
end
schema.rb
ActiveRecord::Schema.define(version: 20140909174718) do
create_table "messages", force: true do |t|
t.string "content"
t.integer "sender_id"
t.integer "recipient_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "users", force: true do |t|
t.string "first_name"
t.string "last_name"
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at"
t.datetime "updated_at"
t.string "current_industry"
t.integer "years_in_current_industry"
t.string "hobbies"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
routes.rb
Catalyst::Application.routes.draw do
devise_for :users, :controllers => { :registrations => "registrations" }
devise_scope :user do
get 'register', to: 'devise/registrations#new'
get 'login', to: 'devise/sessions#new', as: :login
get 'logout', to: 'devise/sessions#destroy', as: :logout
end
resources :users do
member do
get 'edit_profile'
end
resources :messages, only: [:new, :create]
end
resources :messages, only: [:index, :show, :destroy]
root to: "home#index"
match '/about', to: 'static_pages#about', via: 'get'
match '/contact', to: 'static_pages#contact', via: 'get'
match '/help', to: 'static_pages#help', via: 'get'
match '/legal', to: 'static_pages#legal', via: 'get'
end
users_controller
class UsersController < ApplicationController
before_filter :authenticate_user!
def index
#users = User.all
end
def show
#user = User.find(params[:id])
end
def new
end
def create
end
def edit
end
def update
#user = User.find(params[:id])
#user.update!(user_params)
redirect_to #user
end
def destroy
end
def edit_profile
#user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :current_industry, :years_in_current_industry, :hobbies)
end
def sender
#user = User.find(params[:id])
end
def recipient
#user = User.find(params[:id])
end
end
messages_controller
class MessagesController < ApplicationController
before_action :set_recipient
def new
#message = Message.new
#recipient = User.find(params[:user_id])
end
def create
#message = Message.new message_params
if #message.save
flash[:success] = "Your message has been sent!"
redirect_to user_messages_path
else
flash[:failure] = "Please try again."
redirect_to users_path
end
end
private
def message_params
params.require(:message).permit(:content, :sender_id, :recipient_id)
end
end
user.rb
class User < ActiveRecord::Base
has_many :from_messages, class_name: 'Message', :foreign_key => "sender_id"
has_many :to_messages, class_name: 'Message', :foreign_key => "recipient_id"
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :first_name, :last_name, :email, :password, :password_confirmation, :remember_me, :current_industry, :years_in_current_industry, :hobbies
end
message.rb
class Message < ActiveRecord::Base
belongs_to :sender, class_name: "User"
belongs_to :recipient, class_name: "User"
validates :content, presence: true, length: { maximum: 500 }
validates :sender_id, presence: true
validates :recipient_id, presence: true
end
messages/index.html.erb
<h2>Inbox</h2>
messages/new.html.erb
<h1>Create Message</h1>
<%= form_for [#recipient, #message] do |f| %>
<%= f.hidden_field :recipient_id, value: #recipient.id %>
<%= f.label "Enter your message below" %><br />
<%= f.text_area :content %>
<%= f.submit "Send" %>
<% end %>
rake routes
user_messages POST /users/:user_id/messages(.:format) messages#create
new_user_message GET /users/:user_id/messages/new(.:format) messages#new
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
messages GET /messages(.:format) messages#index
message GET /messages/:id(.:format) messages#show
DELETE /messages/:id(.:format) messages#destroy
Models
#app/models/user.rb
class User < ActiveRecord::Base
has_many :messages, class_name: "Message", foreign_key: "recipient_id"
has_many :sent_messages, class_name: "Message", foreign_key: "sender_id"
end
#app/models/message.rb
class Message < ActiveRecord::Base
belongs_to :recipient, class_name: "User", foreign_key: "recipient_id"
belongs_to :sender, class_name: "User", foreign_key: "sender_id"
scope :unread, -> { where read: false }
end
This should give you the ability to create messages which "belong" to a user (IE the recipient), and then you can associate a "sender" profile to those messages.
--
Controllers
This will give you the ability to call the following:
#app/controllers/messages_controller.rb
class MessagesController < ApplicationController
before_action :set_recipient, only: [:new, :create]
def new
#message = current_user.sent_messages.new
end
def create
#message = current_user.sent_messages.new message_params
#message.recipient_id = #recipient.id
#message.save
end
def index
#messages = current_user.messages
end
def destroy
#message = current_user.messages.destroy params[:id]
end
def show
#message = current_user.messages.find params[:id]
end
private
def message_params
params.require(:message).permit(:content, :recipient_id, :sender_id)
end
def set_recipient
#recipient = User.find params[:user_id]
end
end
--
Routes
#config/routes.rb
devise_for :users, path: "", controllers: { :registrations => "registrations" }, path_names: {sign_up: "register", sign_in: "login", sign_out: "logout"}
resources :users do
get :profile
resources :messages, only: [:new, :create] #-> domain.com/users/:user_id/messages/new
end
resources :messages, only: [:index, :show, :destroy] #-> domain.com/messages/:id
--
Views
This will give you the ability to use the following links:
#app/views/users/show.html.erb (user to send message to)
<%= link_to "Send Message", user_messages_path(#user.id) %>
#app/views/messages/new.html.erb
<%= form_for [#recipient, #user] do |f| %>
<%= f.text_field :content %>
<%= f.submit %>
<% end %>
#app/views/messages/index.html.erb
<h2>Inbox</h2>
<% #messages.each do |message| %>
<%= message.content %>
<% end %>
--
Fix
I've read that the thing to do is add the User_id field to the table,
but I'm hoping to link this messages up using sender_id and
recipient_id, which both equal user_id (e.g. User 1[sender] sends a
message to User 2 [recipient])
You don't need to add user_id to your table. user_id is merely a foreign_key, which you've overridden in your models.
All you need to do is set the recipient_id and sender_id, which we're doing in the create method:
def create
#message = current_user.message.new message_params
#message.recipient_id = #recipient.id
#message.save
end
You've done some very clever things here.
Firstly, you have implicitly set the sender_id foreign key by calling current_user.messages. If you had called Message.new, it would have been a completely different story (having to set sender_id)
Secondly, because you're using nested routes, you'll be able to use the #recipient variable you've set in the before_action method to give us the id for the recipient_id.
This should work for you. You won't need to use inverse_of unless you are trying to access "parent" model data in a child / nested model.
Recommendations
What you're doing is completely valid
The core trick is to make sure your Message model is completely separate & independent to your User. This is achieved with your setup, allowing you to create the various objects that you require.
The other aspect you need to consider is how you're going to ensure you're able to provide the users with the ability to have "threaded" messages. You'll achieve this using one of the hierarchy gems, either Ancestry or Closure_Tree
Adding this functionality will be a little more in-depth. I can provide information if you require (just leave a comment)
Threading
The hierarchy gems are actually relatively simple to use.
The trick to "treading" your messages is to use one of these gems (either Ancestry or Closure_Tree), as they provide you with "methods" which you can call on your items. They work by creating several columns in your database, populating them as you save / create the objects you desire
The "threading" issue is a big one, as without the "hierarchy" gems, you won't be able to call the "child" objects of the record you want, thus preventing the threading from occurring. Here's a good Railscast on how to achieve it:
The trick with this is to use something called "recursion"
Recursion is where you create an "indefinite" loop, so far as how "recursive" the data is. EG if you have an object with children, you'll have to cycle through the children, and then the children of those children, recursively until you reach the point of showing all the data:
Recursion is the process of repeating items in a self-similar way. For
instance, when the surfaces of two mirrors are exactly parallel with
each other, the nested images that occur are a form of infinite
recursion.
As such, here's how you to it:
Make sure you save your objects with the correct parents
To display the "threaded" conversation, loop through those parents
Use recursion to loop through their children
We use the ancestry gem, which stores the hierarchy slightly differently to the closure_tree gem we've since discovered (intend to use the closure tree gem soon).
You firstly have to therefore save any hierarchy yourself:
This will allow you to save the various "parents" for that object. This means that when you load the object, and wish to cycle through its descendent, you'll be able to use the Ancestry object methods:
Which means you'll be able to use the following:
#app/views/comments/index.html.erb
<%= render partial: "comments", locals: { collection: #comments } %>
#app/comments/_comments.html.erb
<% collection.arrange.each do |comment, sub_item| %>
<%= link_to comment.title, comment_path(comment) %>
<% if category.has_children? %>
<%= render partial: "category", locals: { collection: category.children } %>
<% end %>
<% end %>
To solve the error you have, try to set :inverse_of attribute of has_many and belongs_to statements in your model classes. You can end up having two has_many - one per each belongs_to reverse:
user.rb:
has_many :from_messages, :class_name => 'Message', :foreign_key => "sender_id", :inverse_of => :sender
has_many :to_messages, :class_name => 'Message', :foreign_key => "to_id", :inverse_of => :recipient
message.rb:
belongs_to :sender, :class_name => 'User', :inverse_of => :from_messages
belongs_to :recipient, :class_name => 'User',:inverse_of => :to_messages
Overall I think your approach is a good starting point for a messaging system. You can try to post your code to https://codereview.stackexchange.com/ for a detailed review.
I have my Model :
class Course < ActiveRecord::Base
include ActiveUUID::UUID
validates :location, :description, presence: true
end
and DB model :
class CreateCourses < ActiveRecord::Migration
def change
create_table :courses, :id => false do |t|
t.uuid :id, :primary_key => true, :null => false
t.datetime :date_start, :null => false
t.float :price, :null => false
t.datetime :date_end
t.text :description
t.text :location, :null => false
t.uuid :mentor_uuid
t.timestamps
end
end
end
and my method in controller which i cal via ajax :
def create
#course = Course.new(params.require(:course).permit(:description, :location))
if #course.save
render json: #course, status: 200
else
render json: #course.errors.full_messages, status: 400
end
end
and here is my ajax call :
var course = {"description" : "Timo", 'location' : 'hahahah'};
$scope.test = function(){
$http.post('api/courses.json', course).success( function (data) {
}).success(function(data){
console.log(data);
}).error(function(data){
console.log(data);
});
};
So this return me an error with : ["Date end can't be blank", "Date start can't be blank", "Price can't be blank"], but what if i want to change error message to my specific one? Also, on error it only returns errors, hwo do i make rails also return "old" model which faild so user dont have to hit face agains the wall and type all the text again from scratch?
Attribute Names
As per this answer & this one, the core problem you have is your attribute name is prepending the error message. The way to fix this is to some how remove the attribute name from the error message:
#config/locales/en.yml
en:
errors:
format: "%{message}"
The default is %{attribute} %{message}
--
We've done it this way before, although I don't think this works in Rails 4:
<%= #model.errors.full_messages.each do |attribute, message| %>
<%= message %>
<% end %>