So I have Votes model, that means a votes for posts. My controller have create action, and it works fine, but when i want to take count, i recive nothing.
See the controller:
class VotesController < ApplicationController
def new
end
def create
#post = Post.find(params[:post_id])
#vote = #post.votes.create(votes_params)
#vote.save
redirect_to #post
end
def index // here is the problem
#post = Post.find(params[:post_id])
#pro = #post.votes.where(stare: false).count
#contra = #post.votes.where(stare: false).count
end
private
def votes_params
params.require(:vote).permit(:stare).merge(user_id: current_user.id)
end
end
Problem is because in index action #post have a nil value... How to repair?
routes.rb:
resources :posts do
resources :votes
collection do
get 'for_vote'
get 'considered'
get 'solved'
end
end
Related
I am trying to create an app where I have Events and each event would have many sales. When a new sale is created it automatically gets an event ID it belongs to. Could somebody please review this and tell me if I am doing something wrong, because I think the way am creating simple_form for the nested model(Sale) is a bit incorrect. Also I am not sure if it should be this way or I ve done something wrong, but when I am accessing nested children the url looks like this
.../events/4/sales/1
.../events/3/sales/1
.../events/5/sales/1
but I would expect it to be like this ?!
.../events/4/sales/1
.../events/4/sales/2
.../events/4/sales/3
Here is my controller and model for Events
class Event < ApplicationRecord
has_many :sales, dependent: :destroy
end
.
class EventsController < ApplicationController
def index
#events = Event.all
end
def new
#event = Event.new
end
def create
#event = Event.new(event_params)
if #event.save
redirect_to #event
else
redirect_to events_path
end
end
def show
#event = Event.find(params[:id])
#sales = #event.sales
end
private
def event_params
params.require(:event).permit(:name, :comment, :event_disscount)
end
end
.
Here is my controller and model for Sales
class Sale < ApplicationRecord
belongs_to :event
has_many :sale_items
accepts_nested_attributes_for :sale_items, allow_destroy: true
end
.
class SalesController < ApplicationController
def new
#sale = Sale.new(event_id: params[:event_id])
#event = Event.find_by(id: params[:event_id])
end
def create
#event = Event.find(params[:event_id])
#sale = #event.sales.create(params[:sale].permit(:receipt_email))
if #sale.save
redirect_to #event
else
redirect_to new
end
end
end
routes.rb
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
resources :events do
resources :sales
end
root 'events#index'
end
And this is how I use simple_form for sale(new)
<%= simple_form_for([#event, #sale]) do |f| %>
My main concern is the 'new' action in Sales controller, whats the best way to create a nested resource with the id of its parent, and then passing this object to the simple_form?!
Thank you in advance
Your question is too broad. Basically you're doing it all right, however, with some improvements on the code it will be easier to find possible problems.
is it correct the way I am creating new sale?
Some improvements over your SalesController:
Create private method sale_params which will sanitize input params from your form. You did it for events already - why not to do it here too?
Since that controller works in the scope of event, params[:event_id] is set for every action. So create a before_action filter which will set your #event variable.
Method create saves the model to the database, so calling save after it makes no sense.
In case of failure on saving #sale to the db redirecting to new is not reasonable. In that case everything user typed in the form will be lost, validation error won't be shown and it will look like a glitch of your app. Render new template instead with the same #sale.
This is how I would rewrite your controller:
class SalesController < ApplicationController
before_action: :set_event
def new
#sale = #event.sales.build
end
def create
#sale = #event.sales.build(sale_params)
if #sale.save
redirect_to #event
else
render action: :new
end
end
private
def sale_params
params.require(:sale).permit(:receipt_email, sale_items_attributes: [])
end
def set_event
#event = Event.find(params[:event_id])
end
end
I've made a very simple blog where users can Create, Edit and Delete posts however I want to add functionality where users can only Edit for a limited time (say 3 days). My understanding of Ruby is not strong enough to know how to do this so any help is appreciated.
This is my Notes (my name for Posts) controller
class NotesController < ApplicationController
before_action :find_note, only: [:show, :edit, :update, :destroy]
def index
#notes = Note.where(user_id: current_user)
end
def show
end
def new
#note = current_user.notes.build
end
def create
#note = current_user.notes.build(note_params)
if #note.save
redirect_to #note
else
render 'new'
end
end
def edit
end
def update
if #note.update(note_params)
redirect_to #note
else
render 'edit'
end
end
def destroy
#note.destroy
redirect_to notes_path
end
private
def find_note
#note = Note.find(params[:id])
end
def note_params
params.require(:note).permit(:title, :content)
end
end
I assume somewhere in the edit method I need to write a rule for restricting the ability to edit posts to only 3 days, using the created_at function somehow? I'm just at a loss as to exactly how to do this.
Any help is appreciated.
Perfect solution for that is :before_filter
class NotesController < ApplicationController
before_filter :check_time!, only: [:edit, :update]
def edit
end
def create
end
private
def check_time!
if Time.now() > #note.created_at + 3.days
flash[:danger] = 'Out of 3 days'
redirect_to note_path(#note)
end
end
end
Experimenting with ruby on rails.. I put a new Post form on a users show page.(i.e. 0.0.0.0:3000/users/2) I'm trying to extract the user's id and insert it into a 'user_id' field in the Post table when you create a new post. So when the form is submitted from the user's page, I can link it to the user that wrote it.
models/post.rb
class Post < ActiveRecord::Base
belongs_to :user
before_save :create_user_id
def create_user_id
self.user_id = current_user
end
end
models/user.rb
class User < ActiveRecord::Base
has_many :posts
end
helpers/application_helper.rb
module ApplicationHelper
def current_user
#current_user ||= User.find(params[:id])
end
end
controllers/post_controller.rb
class PostsController < ApplicationController
def new
#post = Post.new
end
def show
#post = Post.find(params[:id])
#page_title = #post.title.capitalize
#author = User.find(#post.user_id)
#author_url = "/users/" + #post.user_id.to_s
end
def create
#post = Post.create(post_params)
if #post.save
redirect_to #post
else
render 'new'
end
end
# private
private
def post_params
params.require(:post).permit(:title, :body, :user_id)
end
end
The error I get:
Couldn't find User without an ID
Extracted source (around line #15):
#post = Post.find(params[:id])
#page_title = #post.title.capitalize
>>#author = User.find(#post.user_id)
#author_url = "/users/" + #post.user_id.to_s
end
If I test and change my application_helper.rb to this it works, and inserts 2 into the Post's user_id field. The current set up just returns nil
module ApplicationHelper
def current_user
#current_user = 2
end
end
First you want to get the current user, for now you can test using something like this:
#current_user ||= User.find(2)
Note that there will not be an :id param available on a create call, :id refers to a specific member of your resource so in this case if get http://localhost:3000/posts/1 posts would be the resource and 1 would be the param :id so this would not return the current_user you expected.
Then association should do all of the work for you and there is no need for the create_user_id method. All you would have to do is tweak your create method to
#post = current_user.posts.create(post_params)
Right now in my rails 4 app after the user submits a post I want the app to redirect/render the show view, but right now it just goes to the create view. Here is my Posts controller:
class PostsController < ApplicationController
def show
#post = Post.find(params[:id]) # show
end
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
private
def post_params
params.require(:post).permit(:Title, :Body) #whatsoever your post has
end
#redirect_to post_path(#post)
if #post.save
redirect_to #post.find(params[:id])
else
render :new
end
end
Here are my routes:
Rails.application.routes.draw do
root :to => "pages#index"
devise_for :users
resources :users
resources :pages
resources :posts
end
Thanks for your help.
Looks like there's a few bits of code in wrong places - end statements, and your final if statement at the bottom, which doesn't seem to be in any method.
Something like this should work:
class PostsController < ApplicationController
def show
#post = Post.find(params[:id]) # show
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
if #post.save
redirect_to #post.find(params[:id])
else
render :new
end
end
private
def post_params
params.require(:post).permit(:title, :body) #whatsoever your post has
end
end
First, the redirect is wrong. It should be simply:
redirect_to #post
After fixing that, it could be re-rendering because there was an error validating the #post. If #post.save fails the form will be re-rendered, but the URL will stay pointed at the create action.
First time poster, long time lurker here. I have a Users model and controller for a little video game application for Rails that I'm currently making. So I've read a couple of answers on here regarding this issue, but none of the answers really seem to have helped me. People have suggested adding a "user_id" column to my Users table, but my point of contention is, I thought the "user_id" was automatically made in Rails? Even if I use a user.inspect, I still see a user_id=7show up on the page. However, I still get the unknown attribute error when attempting to create a game and assign to the current user. Any help would be most appreciated in pinpointing the cause and solution to this. Thanks!
app/controllers/users_controller.rb:
class UsersController < ApplicationController
skip_before_filter :require_authentication, only: [:new, :create]
def index
#users = User.all
end
def show
end
def new
#user = User.new
end
def edit
#user = current_user
end
def create
#user = User.create!(user_params)
session[:user_id] = #user.id
redirect_to users_path, notice: "Hi #{#user.username}! Welcome to DuckGoose!"
end
def update
current_user.update_attributes!(user_params)
redirect_to users_path, notice: "Successfully updated profile."
end
def destroy
#user = User.find(params[:id])
#user.destroy
redirect_to users_url, notice: 'User was successfully destroyed.'
end
private
def user_params
params.require(:user).permit(:username, :firstname, :lastname, :email, :password, :password_confirmation)
end
end
app/config/routes.rb:
NkuProject::Application.routes.draw do
resources :users do
resources :games
end
resources :sessions
resources :games
get "sign_out", to: "sessions#destroy"
get "profile", to: "users#edit"
root to: "sessions#new"
end
app/controllers/games_controller.rb
class GamesController < ApplicationController
def new
#game = Game.new
end
def index
#games = Game.all
end
def destroy
#game = Game.find(params[:id])
#game.destroy
redirect_to games_url, notice: 'Game was successfully deleted.'
end
def create
#game = current_user.games.build(game_params)
if #game.save
redirect_to #game, notice: "Game successfully added"
else
render :new
end
end
def show
#game = Game.find(params[:id])
end
private
def game_params
params.require(:game).permit!
end
end
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_filter :require_authentication
def current_user
#current_user ||= User.find_by(id: session[:user_id]) if session[:user_id].present?
end
helper_method :current_user
def require_authentication
if current_user
true
else
redirect_to new_session_path
end
end
end
I'm sure I'm missing some code to put in for reference, but if I need anything else please let me know.
Looking at the way your controller actions are defined, I can safely say that User and Game have a 1-M relationship, i.e.,
class User < ActiveRecord::Base
has_many :games
end
class Game < ActiveRecord::Base
belongs_to :user
end
Now, based on that games table must have a field named user_id. Rails is not going to create it for you unless you specify it. You need to add field user_id in games table by creating a migration for the same. Right now, it doesn't seem like you have user_id foreign_key field in games table. Hence, the error while saving games record.