How to access checkbox value through a Controller Hook of Redmine - ruby-on-rails

I'm creating a controller hook of my issues_controller on Redmine. I followed this tutorial.
The question is I couldn't access the checkbox (That I created through a hook on view page) value to set my controller variable. Follow my code
_new_hook.html.erb
<div class="splitcontentright">
<% #user = User.current %>
<b><br><label for="mail_checker_issue"><%= check_box_tag "mail_checker_issue", 1, #user.pref.always_check_email %><%= l(:send_email) %></label></b>
</div>
issues_email_patch.rb
Rails.configuration.to_prepare do
require_dependency 'issue'
class Issue
attr_accessor :mail_checker_issue
end
end
controller_hook.rb
module Redmine_send_emails
module Hooks
class Issues_controller_hook < Redmine::Hook::ViewListener
def controller_issues_new_before_save(context={})
context[:issue].mail_checker_issue = context[:params][:mail_checker_issue]
end
end
end
end
Until where I've checked the hook works well. I've debugged the application and it called correctly the controller_hook method, but I couldn't find the value of my checkbox within the params.
What's wrong? How to do it?

You don't see your checkbox value because you display it before labelled_form_for #issue so it does not belongs to the form.
You can place it here (there are 2 place for hook)
You can try to implement gem deface - I managed to use it in Redmine plugin.

Related

Rails 5, Pundit with namespaced resources

I'm trying to figure out how to use pundit with my namespaced resources.
I've read lots of SO posts from others saying they have problems with this, but those predate discussions on the pundit gem issue tracker. The issue tracker isn't clear about what the solution is - so I'm stuck.
I have folder called Stance, which is a namespace for nested resources, one of which is called overview.
The model.rb file is called:
class Stance::Overview < ApplicationRecord
The controller is called:
class Stance::OverviewsController < ApplicationController
The table in the db is called:
create_table "stance_overviews", force: :cascade do |t|
In my app/policies folder, I've tried various ways of making a policy, with various attempts at then referencing the policy in the views. I can't find a way that works.
I've tried making a folder called Stance with a file called overview_policy.rb, with:
class Stance::OverviewPolicy < ApplicationPolicy
In my organisation view (which has one stance::overview), i define a local variable):
<% if current_user.organisation_id != #organisation.id %>
<%= render 'stance/overviews/internal', overview: #organisation.overview %>
<% else %>
<%= render 'stance/overviews/external', overview: #organisation.overview %>
<% end %>
Then in the view, I'm trying:
<% if policy(overview).show? %>
<p><%= overview.explanation %></p>
<% end %>
I can't find a variation on this that works. Everything I've tried is a guess based on the SO posts, most of which predate the conversations on the pundit issue tracker.
I don't get an error message, but the content doesnt render when it should.
Can anyone see what I need to do to be able to use pundit with namespaced resources?
when I meet the namespace problem, I use Pundit.policy().
For your class, I think should be use Pundit.policy(current_user,[:stance, :overview]).show? in the view and use authorize [:stance, #overview] in the controller.
the Pundit.policy(current_user,[:stance, :overview]).show? will find show? in app/policies/stance/overview_policy.rb.
if you write authorize [:stance, #overview] on show in your controller, it will find show? in app/policies/stance/overview_policy.rb.

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.

How can I call a method on my form controller from my view in Rails?

Newbie to RoR. I can't grasp the concept of how to call a simple method on my form controller from my view. I want to collect 2 pieces of information form the view, call a method on the form controller that will retrieve a piece of information based on the parameters, and then display the piece of information on that same view or another one. Right now, I was trying to use a form controller instance variable to accomplish the displaying of the new piece of information--not sure how I will refresh the view to display it but that is a future hurdle. Right now, I can click my Submit button without getting any errors but it is clearly not hitting my form controller method.
Here is my erb file for the view:
<h1>Enter Required Information</h1>
<%= form_tag (get_hotel_recommendation_path) do %>
<%= label_tag(:name, "Name:") %>
<%= text_field_tag(:name) %>
<%= label_tag(:date, "Date (yyyy-mm-dd):") %>
<%= text_field_tag(:date) %>
<%= submit_tag("Submit") %><br><br>
<%= label_tag(:recommendation, "Recommendation:") %>
<%= #recommended_hotel_name %>
<% end %>
Here is my form controller code:
class RecommendHotelController < ApplicationController
#recommended_hotel_name = ''
def collect_info
end
def get_hotel_recommendation
#recommended_hotel_name = Member.recommended_hotel_name( params[:name], params[:date] )
end
end
I really just want a simple and easy way to do this--not necessarily the best. I just need a quick UI to demonstrate my model code. And I need to get it done soon.
New form controller code:
class RecommendHotelController < ApplicationController
def collect_info
end
def get_hotel_recommendation
redirect_to recommend_hotel_path
end
protected
helper_method :recommended_hotel_name
def recommended_hotel_name
unless (params[:name].nil?)
Member.recommended_hotel_name(params[:name], params[:date])
end
end
end
Once the controller hands over to the view, there's no going back to call additional methods. It is the controller's job to prepare everything the view might need in advance. Once inside the render phase, there's no way to call controller methods.
The exception to this is helper methods which can be called. You need to declare any methods you want to use within your view explicitly. As an example:
helper_method :get_hotel_recommendation
def get_hotel_recommendation
# ...
end
Helper methods can also be located inside the associated helper module, and it's a good idea to put them there if they're used exclusively within views.
In your case, if you're using this only once, you should probably skip the assignment to an instance variable and just return the object in question. The view would look like:
<%= recommended_hotel_name %>
The adjusted controller method:
class RecommendHotelController < ApplicationController
protected
helper_method :recommended_hotel_name
def recommended_hotel_name
Member.recommended_hotel_name(params[:name], params[:date])
end
end
It's worth noting that declaring #recommended_hotel_name = '' in the class context is probably not what you intend. This creates a class variable, not an instance variable. Instance variables in controllers must be defined inside the primary action method or inside a before_filter method. Also remember that instance variables are nil by default, so there's no need to initialize them to that first. An empty string and nil are equivalent when used within a view, everything inside <%= ... %> is converted to a string for you automatically.
Another thing to watch out for is leaving a space between a method name and its arguments. It should be form_tag(...) and not form_tag (...). Normally this does not make a difference, Ruby can be very lenient, but sometimes it can subtly alter the way the arguments are interpreted leading to a lot of confusion as you try to diagnose the problem. Stylistically speaking, only keywords like if, while and case have a space before the brackets as these are not method calls.
As to why your form isn't working, it's not clear. Those parameters should be submitted as you intend, but maybe you're not getting the right routing. Remember it's best to stick with the standard index, new, show, and edit names unless you're doing something exotic. In this case, you should probably define this as index if it shows more than one record or show if it's always one record.
You can get all the information from a form submit in the params array. However, from your example, I would advise to use: form_for instead of using separate form_tags.

Is Property in any way reserved for rails model naming? (Rails pluralisation is killing me.)

I am trying to add a model called Properties in Rails 3.1 So I used created it using ryan bates nifty generator, although the model itself is very basic for now and only includes.
class Property < ActiveRecord::Base
belongs_to :user
end
in my resources I have"
resources :properties
In one of my views I am simply trying to do the following:
<% for property in Property.all %>
<p>description etc</p>
<% end %>
but it gives me the following error?!
undefined method `all' for Property:Module
Now it works if I replace Property.all with User.all or House.all but for some reason Property doesn't work. I'm kinda new to rails and think it has something to do with pluralization but I can't figure it out and its killing me. If anyone could please help that would be epic! Cheers
You can use Inflections to extend default dictionary ( peoperty word is not included by default). The official API can help you with it
In your model definition you need to tell it the real name of your table, eg.
class Property < ActiveRecord::Base
set_table_name "properties"
end
Also you may want to adapt the code slightly for showing your data, it's better to use your controller to grab the data, and the view to display it
In your controller
def index
#properties = Property.all
end
In your view
<% #properties.each do |property| %>
<%= property.description %>
<% end %>

DRYing my views, helper / method / something else?

Have written some RoR sites in the past, but never bothered too much at DRYing up my views as it's only ever been me looking at the code.
Just starting a new site, that is likely to be a collaboration, and need help
I call this line multiple times in my views, and from multiple places.
<%= Person.find_by_id(rider.person_id).name %>
I'd like to be able to just do
<%= get_name(rider.person_id) %>
So I'd assume I'd put this code somewhere
def get_name=(id)
Person.find_by_id(id).name
end
But where? I've tried in the model and as a helper, but always get nomethoderror.
You're wrong in naming this method.
Why you put "=" sign in the method name?
You should call this code only in controller, and in the views, only render result.
The best place for this method is a helper.
def get_person_name_by_id(id)
Person.find_by_id(id).name || nil
end
try application_controller.rb
How about a method on the Rider class that just returns the name?
def name
person = Person.find_by_id( #person_id )
if !person.nil?
return person.name
end
return nil
end
used as
<%= rider.name %>
or, you could use a static/class method on the Person class.
def Person.get_name( rider )
if !rider.nil?
person = find_by_id( rider.person_id )
if !person.nil?
return person.name
end
end
return nil
end
called as
<%= Person.get_name( rider ) %>
Note that I dropped the reference to the id in the view code.
Rails is all about convention over configuration. All of it's helper methods assume the most common options unless overridden. However ActiveRecord models don't have a useful default to_s.
Specifying the default action:
class Person < ActiveRecord::Base
def to_s
name
end
end
Now every time you try to evaluate a person instance in string context you'll get a name.
So
<%= Person.find_by_id(rider.person_id).name %>
Can now be replaced with
<%= rider.person %>
For anything else you can specify field and methods.

Resources