I am new to Rails. I'm having an issue where I am trying to follow a list of users and businesses. I had it working at one point but once I added the MVC for businesses I could no longer follow users, but now I can follow businesses. Any ideas would help me....sadly I've tried fixing this issue for hours...
我是Rails的新手。我有一个问题,我正在尝试关注用户和业务列表。我曾经有过一段时间的工作,但是一旦我为业务添加了MVC,我再也无法关注用户,但现在我可以关注业务了。任何想法都会对我有所帮助....遗憾的是,我已经尝试了几个小时解决这个问题......
MY ERROR:
Started POST "/relationships" for 104.162.78.154 at 2018-04-05 00:57:27 +0000
Processing by RelationshipsController#create as JS
Parameters: {"utf8"=>"✓", "authenticity_token"=>"aForD+VWaioDYY7MwW8cmMoV/3W09VE/fvpJ1GSbRvTqmI17pVZtoWL/coW0QaUKy10qam60FiaqOfNVScFt4w==", "followed_id"=>"5", "commit"=>"Follow"}
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 5], ["LIMIT", 1]]
(0.1ms) begin transaction
CACHE User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 5], ["LIMIT", 1]]
(0.1ms) commit transaction
Rendering relationships/create.js.erb
Relationship Load (0.3ms) SELECT "relationships".* FROM "relationships" WHERE "relationships"."follower_id" = ? AND "relationships"."followed_id" = ? LIMIT ? [["follower_id", 1], ["followed_id", 5], ["LIMIT", 1]]
Rendered users/_unfollow.html.erb (3.9ms)
Rendered relationships/create.js.erb (5.9ms)
Completed 500 Internal Server Error in 22ms (ActiveRecord: 1.7ms)
ActionView::Template::Error (First argument in form cannot contain nil or be empty):
1: <%= form_for(current_user.active_relationships.find_by(followed_id: @user.id),
2: html: { method: :delete },
3: remote: true) do |f| %>
4: <%= f.submit "Unfollow", class: "btn" %>
app/views/users/_unfollow.html.erb:1:in `_app_views_users__unfollow_html_erb__972617426600285045_69864321826040'
app/views/relationships/create.js.erb:1:in `_app_views_relationships_create_js_erb__1827435763454317283_16594120'
Started POST "/relationships" for 104.162.78.154 at 2018-04-05 01:15:50 +0000
Processing by RelationshipsController#create as JS
Parameters: {"utf8"=>"✓", "authenticity_token"=>"aForD+VWaioDYY7MwW8cmMoV/3W09VE/fvpJ1GSbRvTqmI17pVZtoWL/coW0QaUKy10qam60FiaqOfNVScFt4w==", "followed_id"=>"5", "commit"=>"Follow"}
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 5], ["LIMIT", 1]]
(0.2ms) begin transaction
CACHE User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 5], ["LIMIT", 1]]
(0.2ms) commit transaction
Rendering relationships/create.js.erb
Relationship Load (0.6ms) SELECT "relationships".* FROM "relationships" WHERE "relationships"."follower_id" = ? AND "relationships"."followed_id" = ? LIMIT ? [["follower_id", 1], ["followed_id", 5], ["LIMIT", 1]]
Rendered users/_unfollow.html.erb (12.4ms)
Rendered relationships/create.js.erb (16.2ms)
Completed 500 Internal Server Error in 57ms (ActiveRecord: 2.9ms)
MY CODE:
我的代码:
class User < ApplicationRecord
attr_accessor :remember_token, :activation_token, :reset_token
has_many :experiences
has_many :reviews, dependent: :destroy
belongs_to :follower, class_name: "User", optional: true
belongs_to :followed, class_name: "User", optional: true
belongs_to :followerz, class_name: "Business", optional: true
belongs_to :followedz, class_name: "Business", optional: true
has_many :active_relationships, class_name: "Relationship",
foreign_key: "follower_id",
dependent: :destroy
has_many :passive_relationships, class_name: "Relationship",
foreign_key: "followed_id",
dependent: :destroy
has_many :following, through: :active_relationships, source: :followed
has_many :followers, through: :passive_relationships, source: :follower
has_many :active_relationshipzs, class_name: "Relationshipz",
foreign_key: "followerz_id",
dependent: :destroy
has_many :followingz, through: :active_relationshipzs, source: :followedz
has_many :passive_relationshipzs, class_name: "Relationshipz",
foreign_key: "followedz_id",
dependent: :destroy
has_many :followerzs, through: :passive_relationshipzs, source: :followerz
before_save :downcase_email
before_create :create_activation_digest
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
# Returns the hash digest of the given string.
def User.digest(string)
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
end
# Returns a random token.
def User.new_token
SecureRandom.urlsafe_base64
end
# Remembers a user in the database for use in persistent sessions.
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
end
# Returns true if the given token matches the digest.
# Returns true if the given token matches the digest.
def authenticated?(attribute, token)
digest = send("#{attribute}_digest")
return false if digest.nil?
BCrypt::Password.new(digest).is_password?(token)
end
# Forgets a user.
def forget
update_attribute(:remember_digest, nil)
end
# Activates an account.
def activate
update_columns(activated: true, activated_at: Time.zone.now)
end
# Sends activation email.
def send_activation_email
UserMailer.account_activation(self).deliver_now
end
def create_reset_digest
self.reset_token = User.new_token
update_columns(reset_digest: User.digest(reset_token),
reset_sent_at: Time.zone.now)
end
# Sends password reset email.
def send_password_reset_email
UserMailer.password_reset(self).deliver_now
end
# Returns true if a password reset has expired.
def password_reset_expired?
reset_sent_at < 2.hours.ago
end
def feed
following_ids = "SELECT followed_id FROM relationships
WHERE follower_id = :user_id"
Review.where("user_id IN (#{following_ids})
OR user_id = :user_id", user_id: id)
#Review.where("user_id IN (?) OR user_id = ?", following_ids, id)
#followingz_ids = "SELECT followedz_id FROM relationshipsz
# WHERE followerz_id = :business_id"
Experience.where("business_id IN (?) OR business_id = ?", followingz_ids, id)
#Experience.where("business_id IN (#{followingz_ids})
# OR user_id = :user_id", user_id: id)
end
# Follows a user.
def follow(other_user)
active_relationships.create(followed_id: other_user.id)
#following << other_user
end
# Unfollows a user.
def unfollow(other_user)
following.delete(other_user)
end
# Returns true if the
# user is following the other user.
def following?(other_user)
following.include?(other_user)
end
# Follows a Business.
def followz(other_business)
# followingz << other_business
active_relationshipzs.create(followedz_id: other_business.id)
end
# Unfollows a business.
def unfollowz(other_business)
followingz.delete(other_business)
end
# Returns true if the current user is following the other user.
def followingz?(other_business)
followingz.include?(other_business)
end
private
# Converts email to all lower-case.
def downcase_email
email.downcase!
end
# Creates and assigns the activation token and digest.
def create_activation_digest
self.activation_token = User.new_token
self.activation_digest = User.digest(activation_token)
end
end
class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update, :destroy,
:following, :followers]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
def index
@users = User.where(activated: true).paginate(page: params[:page])
@users = User.paginate(page: params[:user])
end
def new
@user = User.new
end
def show
@user = User.find(params[:id])
@reviews = @user.reviews.paginate(page: params[:page])
redirect_to root_url and return unless @user.activated?
end
def create
@user = User.new(user_params)
if @user.save
@user.send_activation_email
flash[:info] = "Please check your email to activate your account."
redirect_to root_url
else
render 'new'
end
end
# Follows a user.
def follow(other_user)
following << other_user
end
# Unfollows a user.
def unfollow(other_user)
following.delete(other_user)
end
# Returns true if the current user is following the other user.
def following?(other_user)
following.include?(other_user)
end
def edit
@user = User.find(params[:id])
end
def update
if @user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to @user
else
render 'edit'
end
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User deleted"
redirect_to users_url
end
def following
@title = "Following"
@user = User.find(params[:id])
@users = @user.following.paginate(page: params[:page])
render 'show_follow'
end
def followers
@title = "Followers"
@user = User.find(params[:id])
@users = @user.followers.paginate(page: params[:page])
render 'show_follow'
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
# Confirms a logged-in user.
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
# Confirms the correct user.
def correct_user
@user = User.find(params[:id])
redirect_to(root_url) unless current_user?(@user)
end
def admin_user
redirect_to(root_url) unless current_user.admin?
end
end
class Relationship < ApplicationRecord
belongs_to :follower, class_name: "User"
belongs_to :followed, class_name: "User"
#validates :follower_id, presence: true
#validates :followed_id, presence: true
belongs_to :followerz, class_name: "User"
belongs_to :followedz, class_name: "Business"
has_many :active_relationships, class_name: "Relationship",
foreign_key: "follower_id",
dependent: :destroy
has_many :active_relationshipzs, class_name: "Relationshipz",
foreign_key: "followerz_id",
dependent: :destroy
end
class RelationshipsController < ApplicationController
before_action :logged_in_user
def create
@user = User.find(params[:followed_id])
current_user.follow(@user)
respond_to do |format|
format.html { redirect_to @user }
format.js
end
end
def destroy
@user = Relationship.find(params[:id]).followed
current_user.unfollow(@user)
respond_to do |format|
format.html { redirect_to @user }
format.js
end
end
end
_follow_form.html.erb
_follow_form.html.erb
<% unless current_user?(@user) %>
<div id="follow_form">
<% if current_user.following?(@user) %>
<%= render 'unfollow' %>
<% else %>
<%= render 'follow' %>
<% end %>
</div>
<% end %>
_follow.html.erb
_follow.html.erb
<%= form_for(current_user.active_relationships.build, remote: true) do |f| %>
<div><%= hidden_field_tag :followed_id, @user.id %></div>
<%= f.submit "Follow", class: "btn btn-primary" %>
<% end %>
_unfollow.html.erb
_unfollow.html.erb
<%= form_for(current_user.active_relationships.find_by(followed_id: @user.id),
html: { method: :delete },
remote: true) do |f| %>
<%= f.submit "Unfollow", class: "btn" %>
<% end %>
create.js.erb
create.js.erb
$("#follow_form").html("<%= escape_javascript(render('users/unfollow')) %>");
$("#followers").html('<%= @user.followers.count %>');
destroy.js.erb
destroy.js.erb
$("#follow_form").html("<%= escape_javascript(render('users/follow')) %>");
$("#followers").html('<%= @user.followers.count %>');
If I had to guess maybe I've been too redundant because for the MVC for the business model which I have not posted...is basically the same thing but I added a "z" to everything(followz...unfollowz....Realtionshipzs...). I am using Cloud9.
如果我不得不猜测也许我太过多了,因为MVC对于我没有发布的商业模式......基本上是一样的但是我给所有东西添加了一个“z”(followz ... unfollowz .. ..Realtionshipzs ...)。我正在使用Cloud9。
1 个解决方案
#1
1
ActionView::Template::Error (First argument in form cannot contain nil or be empty):
1: <%= form_for(current_user.active_relationships.find_by(followed_id: @user.id),
2: html: { method: :delete },
3: remote: true) do |f| %>
4: <%= f.submit "Unfollow", class: "btn" %>
If current_user
has no active relationship with @user
, then your form_for
will have a null argument. You should add an if statement, such that if @user
is not followed, then you cannot unfollow.
如果current_user与@user没有活动关系,那么form_for将具有null参数。您应该添加一个if语句,这样如果不遵循@user,则无法取消关注。
#1
1
ActionView::Template::Error (First argument in form cannot contain nil or be empty):
1: <%= form_for(current_user.active_relationships.find_by(followed_id: @user.id),
2: html: { method: :delete },
3: remote: true) do |f| %>
4: <%= f.submit "Unfollow", class: "btn" %>
If current_user
has no active relationship with @user
, then your form_for
will have a null argument. You should add an if statement, such that if @user
is not followed, then you cannot unfollow.
如果current_user与@user没有活动关系,那么form_for将具有null参数。您应该添加一个if语句,这样如果不遵循@user,则无法取消关注。