Rails: Using Controller as a Model Name - ruby-on-rails-4

I have a model that is called "controller". I checked the rails reserved terms list and it does not show "controller" as a word not to be used.
The model works fine but when I use the model in a view, the view does not submit the controller attribute back to the controller.
Any idea if "controller" is in fact a reserved word?

Yes controller is reserved in RoR. Even you can use it like this in your views:
#to get controller name:
<%= controller.controller_name %>
#to get action name, it is the method:
<%= controller.action_name %>

Related

Rails unedited form fields if db column is NULL

Let me try to present a simple example here:
I have db table Orders and a column delivery_address.
<%= form_for #order do |f| %>
<%= f.text_field :delivery_address %>
<% end %>
If no change is made on the form, when the form is submitted the value of Orders.delivery_address changes from NULL to empty value.
and I set a alert notice which looks like:
test#gmail.com changed delivery_address to .
Any suggestion how to prevent updating db fields with NULL values to empty by default with rails update action.
You could do something like this in the model:
# In the Order model
before_validation do
self.delivery_address = nil if delivery_address.blank?
end
I also really don't like that this happens, but the other alternative is to do it on the controller level

Rails 4.2+: Mapping PostgreSQL JSONB nested values to form fields

I have a users table with a settings field of type JSONB (using PostgreSQL 9.5).
I'm trying to create a form on a settings page to update user.settings["notifications"][...] values.
class User < ActiveRecord::Base
end
user = User.create(settings: { notifications: { post_created: true } })
user.settings["notifications"]["post_created"] # => true
To map the nested JSONB values to a form, however, I have to do this:
# views/form.html.erb
<input type="check" name="user[settings][notifications][post_created]" checked="<%= current_user.settings['notifications']['post_created']" %>
class SettingsController
def update
current_user.settings["notifications"]["post_created"] = params["user"]["settings"]["notifications"]["post_created"]
current_user.save
end
end
Is there anyway to utilize the power of Rails form builders such that I can do:
# will not work, undefined attribute settings['notifications']['post_created']...
<%= form_for current_user, url: settings_path, method: "PUT" do |f| %>
<%= f.check_box "settings['notifications']['post_created']" %>
<% end %>
I understand that Rails is trying to map an attribute from the current_user object, and there isn't really an "attribute" named settings['notifications']['post_created'].
But how does one go about mapping nested JSONB values to a form field for CRUD activity?
A workable (but not really feasible) approach is to created virtual attributes for every single nested value I want to work with:
class User
def settings_notifications_post_created
settings["notifications"]["post_created"]
end
def settings_notifications_post_created=(value)
settings["notifications"]["post_created"] = value
end
end
# view...
<%= f.check_box :settings_notifications_post_created %>
But this loses any benefit of a conventional system since I'm manually typing out every attribute. May as well write raw HTML fields and all the getter/setter methods myself...Googling and Stack Overflow haven't been very helpful so far, it seems there aren't very many with experience doing this kind of stuff yet...

Rails 4: chaining associated objects in Views

Ok, I searched all over the web and found no answer.
I am looking for a way to display a name of a 'category' in the show view of a post (I have to mention I'm rookie in Rails).
I have....
a model "Post"
class Post < ActiveRecord::Base
has_many :categories
belongs_to :user
end
a model "Category"
class Category < ActiveRecord::Base
belongs_to :post
end
and the "show" view of the "post" has a line like this
<%= #post.category.name %>
The error message as screen shot:
NoMethodError in Posts#Show - undefined method `category' for #
The "show" action in "Posts" controller:
def show
#post = Post.find(params[:id])
end
I'm building this app along a little outdated training video on udemy. In this video there's in the category model a line with "attr_accessible"
class Category < ActiveRecord::Base
attr_accessible :name <---------------------- this
has_many :posts
end
...but this does no longer exists since Rails 4.0. Is there another way to retrieve the category name of the post?
Thank you in advance :-)
I got the answer. I found out, that every way, to get the data out of the table categories in the view for products won't work. I than thougt, showing the category in the category show view is simple working. With this idea in mind I took the same code, this one:
app/views/categories/show.html.erb
<p>
<strong>Name:</strong>
<%= #category.category_name %> <--------this line
</p>
...from the category show view and put it into the post show view. I than got again an error but different:
--> NoMethodError in Posts#show
Ok, this says the instance variable "#category" isn't available for the post show view. To change that was easy. I copied the object from the categories controller's show action into the posts controller's the show action. Like this:
class PostsController < ApllicationController
.
.
.
def show
#post = Post.find(params[:id])
#category = Category.find(params[:id])
end
And: it works!!!!
But now, is there something wrong to do it like this?
Cheers.
The method category not exists because the Post model has many "categories" not one "category". The Post should have the method "categories". Then if you want to show a first "category" of post in the view:
<%= #post.categories.first.name %>
If you want to show all "categories" of post, then you iterate the collection:
<% #post.categories.each do |category| %>
<%= category.name %>
<% end %>
I tried again and found the real error in my code. the foreign key was not set by Rails. I had to do manually. The table which has a "belongs_to" (in my case the posts table) needs a foreign key added (like category_id).
First creating the migration file:
rails g migration add_foreign_key_to_posts_table
Second adding the migration code to the migration file:
class AddForeignKeyToPostsTable < ActiveRecord::Migration
def change
add_foreign_key :posts, :categories
end
end
Third raking the db migration with:
rake db:migrate
Fourth adding the foreign key for other resources by following steps one to three. Now everything works fine.

dynamic fields in redmine based upon input

I am using custom fields in redmine. I need a set of custom fields to populate based upon how a user answers a question. for instance, if a user chooses "a" they get a series of 3 custom fields that pertain to "a" ..if a user chooses "b" they get a series of custom fields that pertain to "b" is this possible? any help would be great!
Are You search ready plugin or want to develop your own with neccesary functionality?
In case of develop You may pass selected field from view to controller as parameter. Then check which field was selected and set value to it from other parameter.
I think that somethng like this:
view
<%= form_tag ... do %>
<%= label_tag :selected_field %>
<% select_tag :selected_field, options_for_select(['field1', 'field2',...])
<%= label_tag :value %>
<% text_box_tag :value, value %>
<%= submit_tag 'save' %>
<% end %>
and controller method
def update
obj = SomeClass.find_by... # get your instance
case params[:selected_field]
when 'field1'
obj.field1 = params[:value]
when 'field2'
obj.field2 = params[:value]
end
obj.save
end

Initialize rails form elements in controller for default value like #object.name='John'?

Please tell me a way to assign form elements values in controller itself like:
def new
#form = Model.new
#form.name = 'John'
end
In the controller's new action, create an instance of your model.
def new
#model_object = ModelName.new(name: "John")
end
and in the new.html.erb use the instance that you created in the controller
<%= form_for #model_object %>
This way in the form you will be able to access the value of name attribute.
NOTE:
Do you really want ModelName.new(name: "John") or you meant to use ModelName.new?
Because If you use ModelName.new(name: "John") then every time you create an object of your Model in database(i.e., after submitting form on new page, create action would be called) it will have name as John unless you override it in your view.