Uninitialized constant {"contrller name"}Controller - ruby-on-rails

I am trying to create a new page in my Rails view.
My view is: histories/index.html.erb
My controller is: process_controller.rb
The new page I am trying to create is: histories_paid_out
In my routes.rb, I have:
get "process/histories_paid_out" => "process/histories_paid_out", :as => "histories_paid_out"
And in my process_controller.rb, I have:
def histories_paid_out()
payments = Payments.all
end
And then finally I am calling the controller in my view like this:
<% #histories.each do |history| %>
<%= link_to 'View paid out payments', histories_paid_out_path() %>
<% end %>
But when I cliked the "View paid out payments" link, my Rails app gave me this error:
What's wrong? It is so weird because I think my configuration and setup is already correct.

You should write the singular version of the model. Try this:
def histories_paid_out()
payments = Payment.all
end
Also you will need to define the histories variable somewhere.
Finally, payments will not be available in your view unless you change the scope by calling it #payments instead.

Related

changing record in view via helper

I'm pretty sure that this is a newbie question. I have a users show.html.erb that displays room attributes like: <%=#room.greeting%> and <%=#room.main_text%>.
Now all I want to do is change the #room instance variable when the user presses a button. Simple? - I did think that.
After spending many hours on the internet I have put the following in the show.html.erb
<%= navigation_helper("The Marsh") %> # the Marsh is a room
then I put the following into the helper method
def navigation_helper(params:name)
link_to "Back Out", users_navigation_path(#name )
end
then I put the following into the users controller
def navigation(params:name)
#user.room_name = Room.find_by_name(params:name)
end
And in the routes file:
get 'users/navigation'

Admin-editable views

There doesn't appear to be a gem for this, and I think a CMS is overkill as the client only wants to edit the welcome message on the home page!
Here's what I think I should do:
1) Create Page model:
rails g model Page name:string
2) Create Field model:
rails g model Field name:string content:string page_id:integer
3) Create relationship, Page h1:b2 Field
4) Create rake task to set up the message field that belongs to the welcome page:
namespace :seeder do
namespace :initial_seed do
task pages: :environment do
p = Page.create(name: "Welcome")
p.fields.create(name: "welcomemessage", content: "everything goes here. The long rambling welcome!")
end
end
end
5) Create a 'static' controller for the 'static'-ish pages. The home, the about us etc...
class Static < ApplicationController
def home
#fields = Page.where().fields
end
end
6) In the view, populate the welcome message from the database (I'll create a helper for this):
<% field = #fields.find {|x| x[:name] == 'welcomemessage' } %>
<%= field.content %>
So that's the reading done. Now onto the creation, updation and deletion:
6) Create a control panel controller:
class Panel < ApplicationController
def pages
#pages = Page.all
end
end
7) Display fields in the view at panel/pages.html.erb: (I'll use partials here)
<% #pages.each do |page| %>
Title: <%= page.name %>
<% page.fields.each do |field|%>
Field: <%= field.name %>
<% form_for(field) do |f| %>
<% f.text_area :content%>
<% f.submit %>
<%= end %>
<% end %>
<% end %>
Now this is just a rough run down of what I want to do. There are a few problems I want to query, though.
Is this sort of how you would do this?
How should I configure my routes? What is a clever way of populating the #fields variable (see step 5) with the fields for the page we're viewing?
If I do have a panel/pages.html.erb view, should it simply display all of the editable fields in text areas? How should it update these areas? Multiple submit buttons inside multiple forms? What if someone wants to edit many fields at once and submit them all at once?
Where should these forms go? Should I create multiple RESTful actions all inside the Panel controller like this?:
class Panel < ApplicationController
# new and create not present as the pages have to be created manually
# Enabling the user to create their own pages with their own layouts is a bit insane
def pages
#pages = Page.all
end
def pages_update
end
def pages_destroy
end
end
Multiple restful routes in one controller doesn't strike me as organised, but it would make it easier to lock down the panel controller with a before_action hook to redirect if not admin...
Also, I'm nearing the end of a big job, and all I need to do is add the ability to edit one field on one page and them I'm done and I really don't want to have to figure out alchemy_cms or whatever. In future, yes, but, please, please, please someone give me some small pointers here.
I would strongly advise against building your own CMS. It's fraught with difficulties, and it seems like you're running up against some of those now. You should go and check out something like AlchemyCMS.

Use ActiveAdmin to edit a single record

I have a model that needs editing that is associated with the current user called BillingProfile. How can I add a menu item that links to the edit page of the current user's BillingProfile? I don't want or need an index page for the BillingProfile as a user can only edit their own.
class User
has_one :billing_profile
end
You can use Cancan to manage the ability to allow a User to edit his own Billing Profile.
ability.rb
...
cannot :edit_billing_profile, User do |u|
u.user_id != user.id
end
...
admin/users.rb
ActiveAdmin.register User do
action_item :only => :show do
link_to "Edit BP", edit_bp_path(user.id) if can? :edit_billing_profile, user
end
end
Or you can try something like this:
ActiveAdmin.register User do
form do |f|
f.inputs "User" do
f.input :name
end
f.inputs "Billing Profile" do
f.has_one :billing_profile do |bp|
w.input :address if can? :edit_billing_profile, bp.user
end
end
f.buttons
end
end
I have not test it, but I did something similar on a project.
This may help you-
Adding custom links:
ActiveAdmin.register User, :name_space => :example_namespace do
controller do
private
def current_menu
item = ActiveAdmin::MenuItem.new :label => "Link Name", :url => 'http://google.com'
ActiveAdmin.application.namespaces[:example_namespace].menu.add(item)
ActiveAdmin.application.namespaces[:example_namespace].menu
end
end
end
I basically created a new ActiveAdmin::MenuItem and add it to the current ActiveAdmin menu with the namespace example_namespace and return the menu in the end of the current_menu method. Note: current_menu is a method expected by ActiveAdmin so don't change the name of it. You can add as many items you like and each of these items will be converted to a link on your navigation header. Note this works for ActiveAdmin version > 0.4.3 so you might need to do your own digging if you want to do it for version <= 0.4.3.
I have a LinkHelper defined which has the following two methods:
#This will return an edit link for the specified object instance
def edit_path_for_object_instance(object_instance)
model_name = object_instance.class.to_s.underscore
path = send("edit_#{model_name}_path", object_instance)
end
#This will return an show link for the specified object instance
def show_path_for_object_instance(object_instance)
model_name = object_instance.class.to_s.underscore
path = send("#{model_name}_path", object_instance)
end
You can call the edit_path_for_object_instance method directly from your view and pass in the user.billing_profile object.
This will give you a link directly to the entity resulting a url like /billing_profile/ID/edit
An alternate approach is to use fields_for. This will allow you to create a form for the User attributes and update the associated BillingProfile at the same time. It would look something like this:
<%= form_for #user%>
<%= fields_for #user.billing_profile do |billing_profile_fields| %>
<%= billing_profile_fields.text_field :name %>
<% end %>
<%end%>
See here: http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html

RoR scope issue

I have a users table. It contains a field "user_type".
I added the following scope stmts to the user.rb file:
scope :uemployee, where(:user_type => 'employee')
scope :uclient, where(:user_type => 'client')
scope :ucontractor, where(:user_type => 'contractor')
I created a view and I would like it to list he employees.
Here is the code I'm trying to use:
<% #users.uemployee.each do |user| %>
But, I get "undefined method `uemployee' for nil:NilClass"
What am I doing wrong?
Thanks
Looks like you wanted to do this:
<% User.uemployee.each do |user| %>
But this is considered to be a bad practice. You have to prepare you data in a controller and a view just cycles through it:
# in a controller's action
#users = User.uemployee
#in a view
<% #users.uemployee.each do |user| %>
But even this isn't the best approach. If you create the file views/users/_user.html.erb which shows the info about a particular user (current user will be available as a simple user variable, without the #) then you can simply write:
# in a view
<%= render #users %>
# remember, #users variable was set in your controller
then Rails will cycle through all the users "inside" the #users variable and show them one-by-one.
Your #users collection is nil

how to connect my model to my app

Hey all,(im a beginner in rails)
i've created a controller that look like that:
class HomeController < ApplicationController
def homepage
end
def showmsg
#postword = params[:p]
end
end
the showmsg view looks like that:
<%= #postword %>
and my homepage view looks like that:
<%= form_tag( {:controller => 'home', :action => 'showmsg'}, :method => "post") do %>
<%= text_field_tag(:p,#postword) %>
<%= submit_tag("post") %>
<% end %>
now i have a form that i can write something in it and it will show on the showmsg view.
i created a model with the param :posts with a :description "text" field too.
MY QUESTION is how do i implement the model in the code so any thing i write will be in a list with the things i wrote before, because now (obviously) anything if i write something its deleting the one i wrote before.
thank you all!
I would argue that you're approach is not very rail's like... so if you're learning rails... you're learning it wrong.
Make a Model. Call it "Message":
rails generate model Message content:string
remember to migrate (hopefully you have your databases setup properly):
rake db:migrate
Then in your controller, when you post, you can create message like this:
def create #instead of showmsg... 'create' is the standard name for this
Message.create(params[:message])
#messages = Message.all
end
This will create the message in the database, and then it will get all the messages out of the database and put them into #messages.
You need to edit your form so that it uses form_for. You need to pass it #message, which is an instance of Message.new that your first controller action created. You should call this new
In your create.erb.html file, you show all the messages like this:
<ul>
<% #messages.each do |message| %>
<li><%= message.content %></li>
<% end %>
</ul>
I actually wouldn't recommend showing all the messages in the create action - it should really happen in the index action and you should redirect... but we need to keep this simple. Just google this or watch some of Ryan's screencasts and you'll get it.
And you're done. This is the "Rails Way" to do things. It's best to learn it the way they want you to learn it.
I would also commend that you format your code properly by indenting, and start naming your methods to be real english. For example, showmsg is bad and show_message is a lot better.
If all of this is totally confusing, then just create a new project, and then type:
rails generate scaffold message content:string
It will basically build the application you want and a lot more. You can just read the code and see how they did it.
Hope it helps.
Your approach is not really rails like so some tweaks and fixes are needed. Suggestions: check rails approach to REST. The following code will work it is a little more rails like, but still not all the way there.
Generate a model
rails generate model Message postword:string
this will generate the model and create the migration necessary to create the table in the database.
Create the table
rake db:migrate
Define a post action
It will save the postword in the database. In your controller:
def create
#message = Message.create!(params[:message])
if #message.save
redirect_to "/home/showmsg"
else
render :action => "/home/homepage"
end
end
Create and instance of Message to use in your form
def homepage
#message = Message.new
end
Fix your form tag
<%= form_for #message, :url => "/home/create" do |f| %>
<%= f.label :postword %>
<%= f.text_field :postword %>
<%= f.submit "Create" %>
<% end %>
Now let's show the words in the showmsg page
In the controller select the postwords from the database:
def showmsg
#postwords = Message.all
end
Showing them: /showmsg.html.erb
<H1>postwords list</H1>
<ul>
<% #postwords.each do |p| %>
<li><%= p.postword %></li>
<% end %>
</ul>
Your routes.rb file will have this routes:
get "home/homepage"
get "home/showmsg"
post "home/create"
Define an attribute :new_text in a way similar to this:
class TheModel
# Virtual writer - everything assigned to this attribute
# will be added to self.text
#
def new_text=(v)
self.text += v.to_s
end
def new_text
"" # This is write-only attribute
end
end
Now, use the field 'new_text' in your form.
Of course, this is a very simple example. You should decide whether you want to add the content on every call to :new_text=, maybe some validation would help, the read accessor may need some care, and so on.
For some good guides which may help you start, see the site http://guides.rubyonrails.org/

Resources