i have been learning rails through
http://guides.rubyonrails.org/getting_started.html.
I came across a error while performing save data in controller. The error that comes up when running the blog is :-undefined method `title' for nil:NilClass
**
My code for posts_controller.rb is
**
class PostsController < ApplicationController
def new
end
def create
#post=Post.new(params[:post].permit(:title,:text))
#post.save
redirect_to #post
end
private
def post_params
params.require(:post).permit(:title,:text)
end
def show
#post=Post.find(params[:id])
end
end
**
My code for show.html.rb is
**
<p>
<strong> Title:</strong>
<%= #post.title %>
</p>
<p>
<strong> Text:</strong>
<%= #post.text %>
</p>
**
The code for create_posts.rb
**
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.string :title
t.text :text
t.timestamps
end
end
Please help me out why this error is coming up when I have defined title in create_posts.
All methods defined after private are accessible only internally. Move the show method above private. And make sure you have a file called app/views/posts/show.html.erb and not .rb
Good luck!
# Make sure that you trying to access show method before the declaration of private as we can't access private methods outside of the class.
def show
#post = Post.find(params[:id])
end
def index
#posts = Post.all
end
def update
#post = Post.find(params[:id])
if #post.update(params[:post].permit(:title, :text))
redirect_to #post
else
render 'edit'
end
end
private
def post_params
params.require(:post).permit(:title, :text)
end
end
//vKj
Related
What did I miss?
ERROR: undefined local variable or method `feedback' for #<#<Class:0x007f66dc8dca30>:0x007f66dc8cee80>
Migration:
class CreateFeedbacks < ActiveRecord::Migration
def change
create_table :feedbacks do |t|
t.references :user
t.text :body
t.timestamps
end
end
end
Model:
class Feedback < ActiveRecord::Base
attr_accessible :body, :user
belongs_to :user
end
Controller:
class FeedbacksController < ApplicationController
before_action :authenticate_user!
def index
#feedback = Feedback.all
end
def new
#feedback = Feedback.new
end
def create
#user = User.find(params[:user])
#feedback = #user.feedbacks.create(params[:feedback])
respond_to do |format|
if #feedback.save
format.html { redirect_to #user, notice 'Comment was successfully created.' }
format.json { render json: #feedback, status: :created, location: #feedback }
else
format.html { render action: "new" }
format.json { render json: #feedback.errors, status: :unprocessable_entily }
end
end
end
User model:
has_many :feedback
Routes:
resources :feedbacks
resources :users do
resources :feedbacks
end
Firstly, it helps a lot to style your question and code correctly as well as mark your files (routes.rb, controllers, models correctly). Else it would be very difficult for readers to understand your question and spot issues with your code. You can refer to https://meta.stackoverflow.com/editing-help for the styleguide/ markdown.
Secondly, it looks like your routes.rb are incorrect - but again, this could be due to your formatting. Based on your question, it looks like your routes are:
resources :feedbacks
resources :users do
resources :feedbacks
end
end
When it should be:
resources: users do
resources: feedbacks
end
Thirdly, your seem to have a typo in your model (feedback instead of feedbacks. That is:
class User < ActiveRecord::Base
has_many :feedbacks
end
class Feedback < ActiveRecord::Base
belongs_to :user
end
Lastly, do add specifics and what exactly you ran that caused the error. E.g. did you run something in console, what page did you load?
I am new to ROR and using active admin for generating a small app. I have belongs to and has many relation ships defined in the models. My app is working good for the pages where belongs to does not apply. In the page where belongs to comes into action I have drop down created by Active Admin, however when I select the values from drop down and save the form, values selected from drop down is not getting saved. below are my model controller and active admin pages codes. Please help me fix this issue.
ActiveAdmin.register Componentdetail do
models:
class Preference < ActiveRecord::Base
def permitted_params
params.permit preference: [:prefname, :prefdisplay, :helptext]
end
def preference_params
params.require(:preference).permit(:prefname, :prefdisplay, :helptext)
end
attr_accessible :prefname, :prefdisplay, :helptext
has_many :prefcomprelation
#accepts_nested_attributes_for :prefcomprelation, :allow_destroy => true
def display_name
return self.prefname
end
def input
self.id
end
end
class Prefcomprelation < ActiveRecord::Base
def permitted_params
params.permit prefcomprelation: [:comment, :preference, :componentdetail]
end
def prefcomprelation_params
params.require(:prefcomprelation).permit(:comment, :preference, :componentdetail)
end
# def to_s
# description
# end
attr_accessible :comment, :preference, :componentdetail
#acts_as_list column: :preference, :scope => :preference
belongs_to :preference
#acts_as_list column: :componentdetail, :scope => :componentdetail
belongs_to :componentdetail
validates :comment, presence: true
validates :preference, presence: true
validates :componentdetail, presence: true
#controller do
def new
#prefcomprelation = Prefcomprelation.new
end
def update
#prefcomprelation = Prefcomprelation.new(precomprelation_params)
#prefcomprelation.save
end
def create
#prefcomprelation = Prefcomprelation.new(precomprelation_params)
#prefcomprelation.save
end
#end
end
class Message < ActiveRecord::Base
def permitted_params
params.permit message: [:message, :componentdetail]
end
def message_params
params.require(:message).permit(:message, :componentdetail)
end
attr_accessible :message, :componentdetail
belongs_to :componentdetail
end
class Componentdetail < ActiveRecord::Base
def permitted_params
params.permit componentdetail: [:compname, :compdisplay, :prefcomprelation]
end
def componentdetail_params
params.require(:componentdetail).permit(:compname, :compdisplay, :prefcomprelation)
end
attr_accessible :compname, :compdisplay, :prefcomprelation
has_many :prefcomprelation
#accepts_nested_attributes_for :prefcomprelation, :allow_destroy => true
has_many :message
#accepts_nested_attributes_for :message, :allow_destroy => true
def name
return self.compname
end
end
controllers
class PreferenceController < ApplicationController
def index
#preference = Preference.all
end
def show
end
end
class PrefcomprelationController < ApplicationController
def index
#prefcomprelation = Prefcomprelation.all
end
def create
#prefcomprelation = Prefcomprelation.new(precomprelation_params)
#prefcomprelation.save
end
def new
#prefcomprelation = Prefcomprelation.new(precomprelation_params)
#prefcomprelation.save
end
def show
end
end
class MessageController < ApplicationController
def index
#message = Message.all
end
def create
#message = Message.new(message_params)
#message.save
end
def show
end
end
class ComponentdetailController < ApplicationController
def index
#componentdetail = Componentdetail.all
end
def show
end
end
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
end
Admin Pages
ActiveAdmin.register Preference do
end
ActiveAdmin.register Prefcomprelation do
index do
selectable_column
id_column
column :comment
column :preference
column :created_at
actions
end
filter :comment
filter :preference
filter :componentdetail
form do |f|
f.inputs "Prefcomprelation" do
f.input :comment
#f.inputs do
f.input :preference
f.input :componentdetail
end
f.actions
# f.input :preference
end
end
ActiveAdmin.register Message do
index do
column :message
column :created_at
actions
end
form :html => { :enctype => "multipart/form-data" } do |f|
f.inputs 'Details' do
f.input :message
f.input :componentdetail
end
f.actions
end
end
ActiveAdmin.register Componentdetail do
end
issue comes when I try to create new Prefcomprelation and select preference and componentdetails value from the dropdown menu and try to save.
same happens to the message page.
form do |f|
f.inputs "Product Details" do
f.input :name, :as => :select,
:collection => Product.all.map{|u| ["#{u.product_name}", u.product_name]}
f.input :description
f.input :image
f.input :quantity
end
f.actions
end
Try to add drop down like above and save select value in active admin.
Build some simple project and stack on using accepts nested attributes + form_for.
Now i have no problem with code, all work and save, but when i uncomment accepts_nested_attributes_fori have error or my model doesnt create (i try differente variant for last 5 days, but can t build this right..). I think i have problem in controller.. My code (which works without accepted_nested_attributes).
Model:
class Project < ActiveRecord::Base
belongs_to :user
has_one :j_project
has_one :p_project
# accepts_nested_attributes_for :p_project, :j_project
validates :user_id, :title, presence: true
end
View:
= form_for(#project) do |f|
= f.label :title
= f.text_field :title
= fields_for #p_project do |fa|
= fa.label :requester
= fa.text_field :requester
= fields_for #j_project do |ffa|
= ffa.label :j_login
= ffa.text_field :j_login
= ffa.label :j_password
= ffa.text_field :j_password
= f.submit "Save", class: "btn btn-large btn-primary"
Controller:
class ProjectsController < ApplicationController
def new
#project = Project.new
#p_project = #project.build_p_project
#j_project = #project.build_j_project
end
def create
#project = Project.new(project_params)
#project.user = current_user
#p_project = #project.build_p_project(p_project_params)
#j_project = #project.build_j_project(j_project_params)
if #project.save && #p_project.save && #j_project.save
flash[:success] = "New project was added successfully"
redirect_to user_root_path
else
render 'new'
end
end
private
def project_params
params.require(:project).permit(:title)
end
def p_project_params
params.require(:p_project).permit(:requester)
end
def j_project_params
params.require(:j_project).permit(:j_login, :j_password)
end
end
The problems was with validation:
project_id in j_project and p_project - when I dell them, all works well.
I edit my simple_form and controllers too with guides from internet... But problems, which I cant find in google - was with validation.
The idea is simple. I require a nested attribute tag for user registration. tag requires a user_id.
the view
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: {role: :form}) do |f| %>
<%= f.fields_for :tags, resource.tags.build do |a| %>
<%= a.text_field :tagname %>
<% end %>
<% end %>
tag migration
class CreateTags < ActiveRecord::Migration
def change
create_table :tags do |t|
t.string :tagname
t.references :user, index: true
t.timestamps
end
add_index :tags, :tagname, unique: true
end
end
the tag model
class Tag < ActiveRecord::Base
belongs_to :user
validates_presence_of :user_id
validates_uniqueness_of :tagname
end
the user model
class User < ActiveRecord::Base
has_many :tags, autosave: true, dependent: :destroy
accepts_nested_attributes_for :tags
end
strong parameters
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(
:tags_attributes => [:id, :user_id, :tagname]
) }
The save feature is untouched at the moment. The form passes the nested attribute :tagname just fine. But I've been unable to get the "would be" user_id from resource.
I've already looked for hours online for any answer to this. None has appeared, but the idea that the nested attribute should be saved after the initial user object is saved sounds like a workable solution. But then it's no longer handled as a nested attribute.
Help is appreciated! Thanks!
Solution
Alright I solved it. I bastardised my devise registrations controller a bit, but it works.
First I removed user_id verification from my tag model.
class Tag < ActiveRecord::Base
belongs_to :user
validates_uniqueness_of :tagname
end
I then proceeded with modifying the devise registration controller.
def create
build_resource(sign_up_params)
# added code begins here
#tag = nil
#tag.define_singleton_method(:valid?) {false}
if params["user"].has_key? "tags_attributes"
#tag = Tag.new(params["user"].delete("tags_attributes").values.first)
if #tag.valid?
resource_saved = resource.save # original line of code
else
resource.errors.add(*#tag.errors.first)
flash.delete :tagname_error
set_flash_message :alert, :tag_taken if is_flashing_format?
end
else
set_flash_message :alert, :need_tag if is_flashing_format?
end
# end added code
yield resource if block_given?
if resource_saved
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_flashing_format?
sign_up(resource_name, resource)
# This is where current_user has been created and resource.id == current_user.id
# begin added code
#tag.user_id= resource.id
# end added code
respond_with resource, location: after_sign_up_path_for(resource)
else
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format?
expire_data_after_sign_in!
respond_with resource, location: after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords resource
#validatable = devise_mapping.validatable?
if #validatable
#minimum_password_length = resource_class.password_length.min
end
respond_with resource
end
end
I've defined :tag_taken and :need_tag in my devise locales file for translations of the error string.
And everything works!
For the record this is in addition to the existing code in the question.
I am trying to render a .txt.erb file which uses a presenter to display values. The following code is inside ConfigurationWorker which is perfomed by resque:
#configuration = Configuration.first
#view = Rails.root.join 'lib', 'templates', 'config.txt.erb'
ERB.new(File.read(#view)).result(binding)
The config.txt.erb looks like this (shortened for simplicity):
<% present #configuration do |presenter| %>
Name <%= presenter.name %>
<% end %>
Whereas present is provided by ApplicationHelper and ConfigurationPresenter.
module ApplicationHelper
def present(object, klass = nil)
klass ||= "#{object.class}Presenter".constantize
presenter = klass.new(object, self)
yield presenter if block_given?
return presenter
end
end
class ConfigurationPresenter < ApplicationPresenter
presents :configuration
delegate :name, :configuration
# Presenter methods omitted
end
class ApplicationPresenter
def initialize(object, template)
#object = object
#template = template
end
def self.presents(name)
define_method(name) do
#object
end
end
def method_missing(*args, &block)
#template.send(*args, &block)
end
end
However, this results in NoMethodError: undefined method present for ConfigurationWorker:Class.
I also tried other approaches, like
#configuration = Configuration.first
renderer = ApplicationController.view_context_class.new
renderer.render :file => Rails.root.join('lib', 'templates', 'config.txt.erb')
which results in ActionView::Template::Error: uninitialized constant NilClassPresenter.
What is the proper way to make both the helper and the presenter available and pass in the variables?