Rails 4: Correct way to create objects from other model from the controller - object

Using strong_params from Rails 4, what is the preferred best way to do this?
I used the below solution but are uncertain if this is the best way to do it. ( it works though )
Example:
game_controller.rb ( shortcut version!)
# inside game controller we want to build an Participant object
# using .require fails, using .permits goes true
def GameController < ApplicationController
def join_game_as_participant
#participant = Participant.new(participant_params)
end
end
def participant_params
params.permit(:participant,
:participant_id,
:user_id,
:confirmed).merge(:user_id => current_user.id,
:game_id => params[:game_id])
end

Your participant_params method should be private and you should use the require method :
private
def participant_params
params.require(:participant).permit(
:participant_id, :user_id, :confirmed
).merge(
:user_id => current_user.id, :game_id => params[:game_id]
)
end
Hope this help

Related

how to fix "Rendered ActiveModel::Serializer::Null with Hash"

I am trying to write API for user model, where i have to return only two columns with some modification(appending string)
Every thing work's fine, I even get the correct result, but when I see status code its showing '500', when i check the logs its showed the following error
[active_model_serializers] Rendered ActiveModel::Serializer::Null with Hash
following is the code
1. users_controller.rb
class Api::V1::UsersController < Api::V1::ApiController
# GET
def pl_details
render json: {pl: current_user.pl_url, enabled: current_user.personal_calendar_enabled}, status: :success
end
...
end
user.rb
...
def pl_url
return "#{Rails.application.secrets.app_host}/#{self.calendar_url_token}"
end
...
user_serializer.rb
class UserSerializer < ActiveModel::Serializer
attributes :id, :firstname, :lastname, :email
end
Never mind,
I just did it other way around,I used a separate Serializer to avoid the error, following is the approach
class Api::V1::UsersController < Api::V1::ApiController
# GET
def pl_details
render json: current_user,serializer: PLSerializer, status: :success
end
...
end
and inside PLSerializer
class PLSerializer < ActiveModel::Serializer
attributes :pl, :personal_calendar_enabled
def personal_link
current_user.pl_url
end
end

Access type params from puppet provider

I'm trying to create a perforce custom type devtrack but am stuck in the prefetch stage. There I am trying to use my instances class method to find the correct provider
def self.prefetch(resources)
instances.each do |prov|
if resource = resources[prov.name]
resource.provider = prov
end
end
end
and in the instances class method I try to find all clients on the current host by using the command
p4 workspaces -u
using the below code
def self.get_list_of_workspaces_on_host(host)
ws_strs = p4(['workspaces', '-u', <USERNAME>]).split("\n")
ws_strs.select { |str| str.include?(host) }.map{ |ws| ws.split[1] }
end
def self.get_workspace_properties(ws)
md = /^(\w*)_.*_(main|\d{2})_managed$/.match(ws)
ws_props = {}
ws_props[:ensure] = :present
...
ws_props
end
def self.instances
host = `hostname`.strip
get_list_of_workspaces_on_host(host).collect do |ws|
ws_props = get_workspace_properties(ws)
new(ws_props)
end
end
and the p4 command is defined like
has_command(:p4, "/usr/bin/p4") do
environment :P4PORT => <PERFORCE SERVER>, :P4USER => <USERNAME>
end
The problem I have is that for any p4 command to work I need to access the server, this is specified in the type
devtrack { '36': source => '<PERFORCE SERVER>'}
but how can I access this value from prefetch? The problem beeing that prefetch is a class method and thus can not access the #properties_hash or the resource hash. Is there a way to get around this? Am I designing this completely wrong?

Include monotonically increasing value in logstash field?

I know there's no built in "line count" functionality while processing files through logstash (for various, understandable and documented reasons). But - there should be a mechanism, within any given logstash instance - to have an monotonically increasing variable / count for every parsed line.
I don't want to go the metrics route since it's a continuous polling mechanism (every n-seconds). Alternatives include pre-processing of log files which given my particular use case - is unacceptable.
Again, let me reiterate - I need the ability to generate/read a monotonically increasing variable that I can store during in a logstash filter.
Thoughts?
here's nothing built into logstash to do it.
You can build a filter to do it pretty easily
Just drop something like this into lib/logstash/filters/seq.rb
# encoding: utf-8
require "logstash/filters/base"
require "logstash/namespace"
require "set"
#
# This filter will adds a sequence number to a log entry
#
# The config looks like this:
#
# filter {
# seq {
# field => "seq"
# }
# }
#
# The `field` is the field you want added to the event.
class LogStash::Filters::Seq < LogStash::Filters::Base
config_name "seq"
milestone 1
config :field, :validate => :string, :required => false, :default => "seq"
public
def register
# Nothing
end # def register
public
def initialize(config = {})
super
#threadsafe = false
# This filter needs to keep state.
#seq=1
end # def initialize
public
def filter(event)
return unless filter?(event)
event[#field] = #seq
#seq = #seq + 1
filter_matched(event)
end # def filter
end # class LogStash::Filters::Seq
This will start at 1 every time Logstash is restarted, but for most situations, this would be ok. If you need something that is persistent across restarts, you need to do a bit more work to persist it somewhere
For anyone finding this in 2018+: logstash now has a ruby filter that makes this much simpler. Put the following in a file somewhere:
# encoding: utf-8
def register(params)
#seq = 1
end
def filter(event)
event.set("seq", #seq)
#seq += 1
return [event]
end
And then configure it like this in your logstash.conf (substitute in the filename you used):
ruby {
path => "/usr/local/lib/logstash/seq.rb"
}
It would be pretty easy to make the field name configurable from logstash.conf, but I'll leave that as an exercise for the reader.
I suspect this isn't thread-safe, so I'm running only a single logstash worker.
this is another choice to slove the problem,this work for me,thanks to the answer from the previous person about thread safe. i use seq field to sort my desc
this is my configure
logstash.conf
filter {
ruby {
code => 'event.set("seq", Time.now.strftime("%N").to_i)'
}
}
logstash.yml
pipeline.batch.size: 200
pipeline.batch.delay: 60
pipeline.workers: 1
pipeline.output.workers: 1

page-object gem seems not working

I am trying to use page-object gem in my watir-webdriver scripts and I think I might be missing something.
Here is my code for log_in.rb:
require "./all_deals"
class LogIn
include PageObject
text_field(:email, :id => 'UserName')
text_field(:password, :id => 'Password')
checkbox(:remember_me, :id => 'RememberMe')
button(:log_me_in, :value => 'Login')
def initialize(browser)
#browser = browser
end
def log_in (email, password)
self.email = email
self.password = password
remember_me
log_me_in
AllDeals.new(#browser)
end
end
My home_page.rb
require "./log_in"
class HomePage
def initialize(browser)
#browser = browser
end
def visit
#browser.goto "http://treatme.co.nz/"
end
def go_to_log_in
#browser.goto "https://treatme.co.nz/Account/LogOn"
LogIn.new(#browser)
end
end
Here is my log_in_test.rb
require "rubygems"
require "test/unit"
require "watir-webdriver"
require "page-object"
require "./home_page"
class LogInTest < Test::Unit::TestCase
def setup
#browser ||= Watir::Browser.new :firefox
end
def teardown
#browser.close
end
def test_fail
#home_page = HomePage.new(#browser)
#home_page.visit
#log_in_page = #home_page.go_to_log_in
#all_deals = #log_in_page.log_in("test#gmail.com","test")
assert (#all_deals.get_title == "GrabOne Daily Deals - Buy Together, Save Together")
end
end
The result of the test run is:
Finished tests in 22.469286s, 0.0445 tests/s, 0.0000 assertions/s.
1) Error:
test_fail(LogInTest):
NoMethodError: undefined method `text_field_value_set' for nil:NilClass
C:/Ruby193/lib/ruby/gems/1.9.1/gems/page-object-0.9.2/lib/page-object/accessors.rb:142:in `block in text_field'
I am using Ruby 1.9 with page-object gem 0.9.2.
Can you please help me?
Also in each of those rb file, I need to require the class files it references, is there a way I don't have to declare it every time?
Thanks so much.
Addressing the Exception
That exception is occurring do to the LogIn page re-defining the initialize method.
class LogIn
include PageObject
def initialize(browser)
#browser = browser
end
end
When you include PageObject, it already adds a specific initialization method. Your class is overriding that initialization and presumably causing something to not get setup correctly.
Removing the initialize method will get you past that exception.
However, you will then hit a remember_me is not a variable/method exception. Assuming you want to check the checkbox, it should be check_remember_me.
Requiring Class Files
I usually have my test file require a file that requires all my page_objects. It is a similar concept to how your would require any other gem or library.
For example, I would create a treatme.rb file with:
require 'log_in'
require 'home_page'
Assuming you require the files in the required order (ie files that are needed by others are required first), none of your page object files (ie log_in.rb and home_page.rb) should need to do any requiring.
Your test files would then just require your treatme.rb file. Example:
require './treatme'

Are there equivalents to Ruby's method_missing in other languages?

In Ruby, objects have a handy method called method_missing which allows one to handle method calls for methods that have not even been (explicitly) defined:
Invoked by Ruby when obj is sent a message it cannot handle. symbol is the symbol for the method called, and args are any arguments that were passed to it. By default, the interpreter raises an error when this method is called. However, it is possible to override the method to provide more dynamic behavior. The example below creates a class Roman, which responds to methods with names consisting of roman numerals, returning the corresponding integer values.
class Roman
def romanToInt(str)
# ...
end
def method_missing(methId)
str = methId.id2name
romanToInt(str)
end
end
r = Roman.new
r.iv #=> 4
r.xxiii #=> 23
r.mm #=> 2000
For example, Ruby on Rails uses this to allow calls to methods such as find_by_my_column_name.
My question is, what other languages support an equivalent to method_missing, and how do you implement the equivalent in your code?
Smalltalk has the doesNotUnderstand message, which is probably the original implementation of this idea, given that Smalltalk is one of Ruby's parents. The default implementation displays an error window, but it can be overridden to do something more interesting.
PHP objects can be overloaded with the __call special method.
For example:
<?php
class MethodTest {
public function __call($name, $arguments) {
// Note: value of $name is case sensitive.
echo "Calling object method '$name' "
. implode(', ', $arguments). "\n";
}
}
$obj = new MethodTest;
$obj->runTest('in object context');
?>
Some use cases of method_missing can be implemented in Python using __getattr__ e.g.
class Roman(object):
def roman_to_int(self, roman):
# implementation here
def __getattr__(self, name):
return self.roman_to_int(name)
Then you can do:
>>> r = Roman()
>>> r.iv
4
I was looking for this before, and found a useful list (quickly being overtaken here) as part of the Merd project on SourceForge.
Construct Language
----------- ----------
AUTOLOAD Perl
AUTOSCALAR, AUTOMETH, AUTOLOAD... Perl6
__getattr__ Python
method_missing Ruby
doesNotUnderstand Smalltalk
__noSuchMethod__(17) CoffeeScript, JavaScript
unknown Tcl
no-applicable-method Common Lisp
doesNotRecognizeSelector Objective-C
TryInvokeMember(18) C#
match [name, args] { ... } E
the predicate fail Prolog
forward Io
With footnotes:
(17) firefox
(18) C# 4, only for "dynamic" objects
JavaScript has noSuchMethod, but unfortunately this is only supported by Firefox/Spidermonkey.
Here is an example:
wittyProjectName.__noSuchMethod__ = function __noSuchMethod__ (id, args) {
if (id == 'errorize') {
wittyProjectName.log("wittyProjectName.errorize has been deprecated.\n" +
"Use wittyProjectName.log(message, " +
"wittyProjectName.LOGTYPE_ERROR) instead.",
this.LOGTYPE_LOG);
// just act as a wrapper for the newer log method
args.push(this.LOGTYPE_ERROR);
this.log.apply(this, args);
}
}
Perl has AUTOLOAD which works on subroutines & class/object methods.
Subroutine example:
use 5.012;
use warnings;
sub AUTOLOAD {
my $sub_missing = our $AUTOLOAD;
$sub_missing =~ s/.*:://;
uc $sub_missing;
}
say foo(); # => FOO
Class/Object method call example:
use 5.012;
use warnings;
{
package Shout;
sub new { bless {}, shift }
sub AUTOLOAD {
my $method_missing = our $AUTOLOAD;
$method_missing =~ s/.*:://;
uc $method_missing;
}
}
say Shout->bar; # => BAR
my $shout = Shout->new;
say $shout->baz; # => BAZ
Objective-C supports the same thing and calls it forwarding.
This is accomplished in Lua by setting the __index key of a metatable.
t = {}
meta = {__index = function(_, idx) return function() print(idx) end end}
setmetatable(t, meta)
t.foo()
t.bar()
This code will output:
foo
bar
In Common Lisp, no-applicable-method may be used for this purpose, according to the Common Lisp Hyper Spec:
The generic function no-applicable-method is called when a generic function is invoked and no method on that generic function is applicable. The default method signals an error.
The generic function no-applicable-method is not intended to be called by programmers. Programmers may write methods for it.
So for example:
(defmethod no-applicable-method (gf &rest args)
;(error "No applicable method for args:~% ~s~% to ~s" args gf)
(%error (make-condition 'no-applicable-method :generic-function gf :arguments args) '()
;; Go past the anonymous frame to the frame for the caller of the generic function
(parent-frame (%get-frame-ptr))))
C# now has TryInvokeMember, for dynamic objects (inheriting from DynamicObject)
Actionscript 3.0 has a Proxy class that can be extended to provide this functionality.
dynamic class MyProxy extends Proxy {
flash_proxy override function callProperty(name:*, ...rest):* {
try {
// custom code here
}
catch (e:Error) {
// respond to error here
}
}
Tcl has something similar. Any time you call any command that can't be found, the procedure unknown will be called. While it's not something you normally use, it can be handy at times.
In CFML (ColdFusion, Railo, OpenBD), the onMissingMethod() event handler, defined within a component, will receive undefined method calls on that component. The arguments missingMethodName and missingMethodArguments are automatically passed in, allowing dynamic handling of the missing method call. This is the mechanism that facilitated the creation of implicit setter/getter schemes before they began to be built into the various CFML engines.
Its equivalent in Io is using the forward method.
From the docs:
If an object doesn't respond to a message, it will invoke its "forward" method if it has one....
Here is a simple example:
Shout := Object clone do (
forward := method (
method_missing := call message name
method_missing asUppercase
)
)
Shout baz println # => BAZ
/I3az/
Boo has IQuackFu - there is already an excellent summary on SO at how-can-i-intercept-a-method-call-in-boo
Here is an example:
class XmlObject(IQuackFu):
_element as XmlElement
def constructor(element as XmlElement):
_element = element
def QuackInvoke(name as string, args as (object)) as object:
pass # ignored
def QuackSet(name as string, parameters as (object), value) as object:
pass # ignored
def QuackGet(name as string, parameters as (object)) as object:
elements = _element.SelectNodes(name)
if elements is not null:
return XmlObject(elements[0]) if elements.Count == 1
return XmlObject(e) for e as XmlElement in elements
override def ToString():
return _element.InnerText

Resources