I'm having trouble with showing the articles after added has_many and belongs_to.my codes are like this.
models/blog_post.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
has_many :blog_posts, inverse_of: :user
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:omniauthable
mount_uploader :image, ImageUploader
end
models/user.rb
class BlogPost < ApplicationRecord
belongs_to :user, inverse_of: :blog_posts
end
controllers/blog_posts_controller.rb
class BlogPostsController < ApplicationController
before_action :authenticate_user!
def new
#bp = BlogPost.new
end
def create
#bp = BlogPost.new
#bp.user_name = current_user
#bp.title = params[:blog_post][:title]
#bp.content = params[:blog_post][:content]
#bp.save
redirect_to blog_post_path(#bp.id)
end
def show
#bp = BlogPost.find(params[:id])
end
def destroy
#bp = BlogPost.find(params[:id])
#bp.destroy
redirect_to root_path(#bp)
end
end
views/blog_posts/new.html.slim
h1 Let's post your article!
= form_for #bp do |f|
h2 title
= f.text_field :title
h2 content
= f.text_area :content
br
= f.submit "Submit"
a href="/" Home
views/blog_posts/show.html.slim
h2 name
p = #user.user_name
h2 title
p = #bp.title
h2 content
p = #bp.content
a href="/"Home
and I get this error...
ActionController::UrlGenerationError in BlogPostsController#create``No route matches {:action=>"show", :controller=>"blog_posts", :id=>nil} missing required keys: [:id]
Is there any idea of solving this problem?
seems like the BlogPost is not saved and that's why its redirecting it with id = nil
Try changing the code to
if #bp.save
redirect_to blog_post_path(#bp.id)
else
render :edit
end
Try to redirect to your newly created object #bp, you don't really require the blog_post_path(#bp.id)
The following should also work fine
def create
#bp = BlogPost.new
#bp.user_name = current_user
#bp.title = params[:blog_post][:title]
#bp.content = params[:blog_post][:content]
respond_to do |format|
if #bp.save
redirect_to #bp, notice: 'Blog Post was successfully created.'
else
render :edit
end
end
end
However, it might also be that your routes are not correctly set, if the above is not working, please share your config/routes.rb file to see how is it defined.
you can also define it like this in your file
config/routes.rb
resources :blog_posts
Related
I have an application with users using devise for authentication, in the user model I have added in the database a column called admin with false value by default. that way I have managed to have access as administrator to certain parts of the application.
I have a subscription model and each user when authenticated gets a free value by default. what I want to achieve is that the admin user in your user list can be able to switch from free to premium. this is the code i have and i can't get it to work.
Users Model:
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
#Validaciones
validates :nombre, :apellido, presence: true
devise :database_authenticatable, :validatable, password_length: 8..128
#Relaciones
has_many :patients, dependent: :destroy
has_many :articles, dependent: :destroy
has_one :profile, dependent: :destroy
has_one :suscription, dependent: :destroy
#Creación de perfil
after_create :set_profile
def set_profile
self.profile = Profile.create()
end
#Creación de suscripcion
after_create :set_suscription
def set_suscription
self.suscription = Suscription.create()
end
end
Suscription Model:
class Suscription < ApplicationRecord
belongs_to :user
enum status: {
free: 0,
premium: 1
}
end
Users controllers:
class UsersController < ApplicationController
def index
#pagy, #users = pagy(User.order(created_at: :asc), items:12)
end
def show
#user = User.find(params[:id])
end
end
Suscriptios controller:
class SuscriptionsController < ApplicationController
before_action :set_suscription
def show
end
def edit
end
def update
#suscription = Suscription.find(params[:id]).update_params
redirect_to profile_path
flash[:notice] = "La suscripción ha sido actualizada"
end
private
def set_suscription
#suscription = (current_user.suscription ||= Suscription.create)
end
def suscription_params
params.require(:suscription).permit(:status)
end
end
Route:
#UPDATE PREMIUM
patch "suscriptions", to:"suscriptions#update", as: "user_premium"
View (Link):
<%= link_to 'Update', user_premium_path ,method: :patch %>
This should fix it:
subscriptions_controller.rb
def update
#suscription = Suscription.find(params[:id]).update(subscription_params)
redirect_to profile_path
flash[:notice] = "La suscripción ha sido actualizada"
end
view
<%= link_to 'Update', user_premium_path(id: #subscription.id, status: "premium"), method: :patch %>
One other thing that is not needed, but normally I would see something like this in a controller:
private
def set_suscription
#suscription = Suscription.find(params[:id])
end
which then makes your update method look like this:
def update
#subscription.update(subscription_params)
redirect_to profile_path
flash[:notice] = "La suscripción ha sido actualizada"
end
This is all assuming you are simply trying to update the subscription from free to premium with your link_to. I wouldn't recommend doing anything like this, because what if someone accidentally marks this? They can no longer go back to a free subscription. Maybe have a modal open that is routed to subscription edit with a drop down to select the status would be better?
I am using the Rails "Getting Started" blog post exercise, and trying to integrate with Devise for authentication and authoring of posts.
When creating an Article, the Author should be the currently logged-in user.
I am getting an error when trying to Create an Article. I know that the error is in my Articles controller, but I can't seem to figure out how to grab the current logged-in Author to kick off the creation of an Article. I believe I did the relationship properly between an Author and an Article.
Error: undefined method `articles' for nil:NilClass
Author Model:
class Author < ApplicationRecord
has_many :articles
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
Articles Model:
class Article < ApplicationRecord
belongs_to :author
has_many :comments, dependent: :destroy
validates :title, presence: true,
length: { minimum: 5 }
end
Articles Controller:
class ArticlesController < ApplicationController
def index
#articles = Article.all
end
def show
#article = Article.find(params[: id])
end
def new
#article = Article.new
end
def edit
#article = Article.find(params[: id])
end
def create
#author = #current_author
#article = #author.articles.create(article_params)
if #article.save
redirect_to #article
else
render 'new'
end
end
def update
#article = Article.find(params[: id])
if #article.update(article_params)
redirect_to #article
else
render 'edit'
end
end
def destroy
#article = Article.find(params[: id])
#article.destroy
redirect_to articles_path
end
private
def article_params
params.require(: article).permit(: title,: text,: author)
end
end
Try removing the # from #current_author. With devise, current_author is a method that returns the user by session[:user_id] not an instance variable.
Also, try doing one of three things....
Change #author.articles.create(atricle_params) to #author.articles.new(atricle_params)
Move the assignment of the author to the 'new' method as so...
def new
#article = Article.new
#article.author = current_user
end
Add a hidden_field to your form...
'<%= f.hidden_field :author_id, current_user.id %>
'
Hello everyone I am new to rails and for some reason I keep getting an error
undefined method 'user' for nil:NilClass.
I have pasted an image of the error on the bottom and I posted the code below.
Image Error
# registeredapps_controller.rb
class RegisteredappsController < ApplicationController
def create
#registeredapp = Registeredapp.new(registeredapp_params)
#registeredapp.user = current_user
unless RegisteredappPolicy.new(current_user, #registeredapp).create?
flash[:alert] = "not authorized"
redirect_to user_registeredapps_path(current_user.id)
end
if #registeredapp.save
flash[:notice] = "You successfully registered your app."
redirect_to user_registeredapp_path(current_user.id, #registeredapp.id)
else
flash.now[:alert] = "There was an error registering your app. Please try again."
render :new
end
end
Policies (using Pundit Gem)
# registeredapp_policy.rb
class RegisteredappPolicy
def initialize(user, registeredapp)
#registeredapp = registeredapp
#user = user
end
def create?
if #user.present?
#user = #registerdapp.user
else
false
end
end
Here are my models
# models/user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
def avatar_url(size)
gravatar_id = Digest::MD5::hexdigest(self.email).downcase
"http://gravatar.com/avatar/#{gravatar_id}.png?s=#{size}"
end
has_many :registeredapps
end
# models/registeredapp.rb
class Registeredapp < ApplicationRecord
belongs_to :user
has_many :events
end
Your issue is that the instance variable #registeredapp is mispelled in the RegisteredappPolicy class under the create? method.
It currently is
def create?
if #user.present?
#user = #registerdapp.user
else
false
end
end
whereas the variable defined in the initialize is #registeredapp you're missing an e
#registerdapp is nil
#user = #registerdapp.user
use try
#user = #registerdapp.try(:user)
or
def create?
if #user.present? && #registerdapp.present?
#user = #registerdapp.user
else
false
end
end
NOTE: Also you are missing one end for if else in create? method
Rails convention usually is to have the model name like:
User
And its corresponding table name like:
users
In your ActiveRecord::Registeredapp you have :user, check if you shouldn't have :users.
Hey there,
I am fairly new to Rails and I've managed to create a Favorite controller for my Items(Tools) and Users, which works totally fine.Now I am trying to do the same just in that user module. So users are able to favorite other users. I played around, and came up with this:
I am getting this error in the browser when accessing /users/index view:
NoMethodError in Users#index
undefined method `favorite_user_path' for #<#<Class:0x8ca77b8>:0x8ca50b8>
Here is my code:
app/models/favorite_user.rb
class FavoriteUser < ActiveRecord::Base
belongs_to :c_user_id
belongs_to :user_id
end
app/models/user.rb
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_many :tools
# Favorite tools of user
has_many :favorite_tools # just the 'relationships'
has_many :favorites, through: :favorite_tools, source: :tool # the actual tools the user favorites
# Favorite users of user
has_many :favorite_users # just the 'relationships'
has_many :userfavorites, through: :favorite_users, source: :user # the actual users the user favorites
has_many :userfavorited_by, through: :favourite_users, source: :user # the actual users favoriting a user
mount_uploader :avatar_filename, AvatarUploader
end
app/controllers/users_controller.rb
class UsersController < ApplicationController
before_action :find_user, only: [:show, :favorite]
# Add and remove favorite recipes
# for current_user
def userfavorite
type = params[:type]
if type == "favorite"
current_user.userfavorites << #user
elsif type == "unfavorite"
current_user.userfavorites.delete(#user)
else
# Type missing, nothing happens
redirect_to :back, notice: 'Nothing happened.'
end
end
def index
#users = User.all
end
def show
#tools = Tool.where(user_id: #user).order("created_at DESC")
#tool = Tool.find(1)
end
private
def find_user
#user = User.find(params[:id])
end
end
app/views/users/index.html.haml
- #users.each do |user|
= image_tag gravatar_for user if user.use_gravatar == true
= image_tag user.avatar_filename.url if user.use_gravatar == false
%h2= link_to user.username, user
%p= link_to "Favorite", favorite_user_path(user, type: "favorite"), method: :get
%p= link_to "Unfavorite", favorite_user_path(user, type: "unfavorite"), method: :get
app/config/routes.rb
resources :users, only: [:index, :show, :userfavorite] do
get :userfavorite, on: :member
end
I hope the provided data is enough, if not please tell me. I'm grateful for all Your replies.
You haven't declared any such path in the routes file. As per your routes file you can use named path like
userfavorite_user_path(user_id)
As the title suggests, I am building a Q&A application (Like ask.fm) in Ruby on Rails, and I am having some trouble with sending the question to a specific user.
I have 3 models, a User model (from Devise), A Question model with this attribute: content:text and a Answer model with this attribute: content:text
Here are their models
class Answer < ActiveRecord::Base
belongs_to :question
belongs_to :user
end
class Question < ActiveRecord::Base
has_one :answer
belongs_to :user
end
class User < ActiveRecord::Base
has_many :questions
has_many :answers
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
And here are the migrations that I created
This one adds a user_id to the question (So I can check which user sent the question, btw this works fine)
class AddUserIdToQuestion < ActiveRecord::Migration
def change
add_column :questions, :user_id, :integer
end
end
Here I tried to add a receiver (the user that would get the question) but I wont work, when I create a Question It will be equal to 'nil', when I check it out in the rails console (Check the controller to see what I did)
class AddReceiverToQuestion < ActiveRecord::Migration
def change
add_column :questions, :receiver, :integer
end
end
Here is the question controller
class QuestionsController < ApplicationController
def new
#question = Question.new
end
def create
#question = Question.new(question_params)
#question.user_id = current_user.id
if #question.save
redirect_to root_path
else
render 'new'
end
end
private
def question_params
params.require(:question).permit(:content, :user_id)
end
end
I also have a user profile page where I have a form show up, here is the controller for that one
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
#user_questions = #user.questions
#question = Question.new
end
def create
#user = User.find(params[:id])
#question = Question.new(question_params)
#question.receiver = #user.id #This does not work
if #question.save
redirect_to root_path
else
render 'new'
end
end
private
def question_params
params.require(:question).permit(:content, :user_id, :receiver)
end
end
I really hope some of you know what I could do here, thank you :)